萬萬沒想到之Java編碼的問題

以爲很簡單的問題耗時一天,尚未有完美解決方案。。

解決方案以及分析參閱: 

http://www.360doc.com/content/13/0830/14/1073512_310953718.shtml

關鍵字:Java中文字符編碼亂碼詳述

http://javarevisited.blogspot.com/2012/01/get-set-default-character-encoding.html

關鍵字: How to get and set default Character encoding or Charset in Java

詳情待我慢慢道來。。。


項目需求: 解析java文件,從中獲取package, class, method, testng的annotation等。

本來這個東西用ruby已經實現了,而且工作良好,但是因爲平臺的問題,非要重新用java實現。。。擦

自然而然找到了javaParser,用起來還是很順手。

但是項目要求打包成可執行的jar文件,這就苦了我了。


把我們另外一個項目的拿過來做測試包,使用eclipse運行,完美無誤。

但是打包之後通過命令行運行就是各種錯誤。

基本上就是遇到了中文,以色列語(希伯來語)的時候出的錯誤。

之前對java編碼這塊也不是很熟(常年用ruby, python解決這類字符串問題),真的不知道水能有tm這麼深!


首先嚐試讀入和寫入的編碼。

先講下IO流的轉換過程。

從github上下載項目壓縮包 -> 讀入zipinputstream -> 然後將符合條件的文件(至少得是java吧,至少裏面得有@Test吧)轉換成inputstream傳給JavaParser,然後由其解析。

錯誤就出在inputstream傳給javaParser這塊。

一開始一直以爲是我轉換到inputstream時的問題,然後使用utf-8從zipinputstream切到inputstream,然後將inputstream給javapaser, 同時給javaparser一個utf-8的參數讓它按照這個編碼讀。。。

經過2個多小時的折騰,發現我擦,完全沒用。

其間遇到狀況是這樣的: 使用utf-8吧,一部分文件解析失敗。不使用吧,這些沒問題了,另外一些突然又有問題了。。。

其間還遇到了utf-8還是utf8還是UTF-8的問題。。。


經過又1個多小時的折騰,發現還是沒思路,然後找來大牛(因爲很壯,跟牛很像)幫忙。


大牛的思路(等下你會看到也挺奇葩的,哈哈):

對,是編碼的問題,那麼我們看看這些文件都是什麼類型的編碼呢,我們按照類型進行讀入不就行了?(這裏完全正確!但是後面就給帶偏了。。)

發現大部分文件是沒有編碼格式的,然後少部分是使用utf-8保存的。

思路就是如果沒有格式的,我們使用最廣泛能兼容的格式,用到了iosxxxx-15的一個格式,有格式的使用默認格式,當然就是utf-8了。

這下問題少了很多,但是還是有文件不能正確解析。

我們的要求是必須要全部兼容,因爲涉及到很多個項目,不可能因爲你的問題改人家項目的代碼。哭。


解析來就到了好玩的地方了:我們把這些中文,希伯來語都刪掉吧!

嗯?!好主意啊(我也是腦子進水了)。於是我們找到了

text.replaceAll("[^\\x00-\\x7F]", "")

這個可以替換掉所有非acsii碼(待確定是不是這個意思,有熟知大叔請幫忙評論下,多謝多謝!)。

不錯不錯,這下子又解決了不少有問題的文件。

然後大牛要回家陪老婆過週末blabla就走掉了。。。


然後我繼續繼續努力吧(繼續進水中。。)


慢慢發現這以後出的問題就不是解析語言的問題,而是突然發現經常會丟掉雙引號。

比如正常的 String a = "bbb";就變成了 String a = "bbb;

這個就沒辦法了。。

等等,我想到一個好主意,正則表達式!(回想起來,慚愧的要撞牆自殺)


我試着將出現這類問題的line通過正則表達式判斷出來,然後通過替換將雙引號加上。

(說道這裏發現一道不錯的面試題:使用java如何判斷在一個字符串裏,特定單詞的數量。 答案見最後)

然後

然後發現了這樣的:

String s1 = "private String receipt	= \"特典が適用され、PayPalの領収書に表示されます;"; #分號前少一個雙引

接着發現了這樣的:

String s2 = "ppBtnPage.setAttributeValue(\"billing_first_name\", \"劉);"; <span style="font-family: Arial, Helvetica, sans-serif;">#括號前少一個雙引</span>

我心想這就差不多了吧,這正則寫的也夠複雜了,我擦,理論上不應該這麼玩啊。

終於當我看到還有這樣的,我就崩潰了,嚴格意義上是腦子的水被清空了

String s3 = "@Test (testName=\"19947,groups={\"RQA_HK\", \"RQA_zh\", \"RQA_APAC\" },description=\"HSS SPARTA FLOW\")"; <pre code_snippet_id="451465" snippet_file_name="blog_20140815_2_725999" name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">#TMD字符串中間少一個雙引</span>


終於醒悟過來了: 你讀的時候編碼就是錯誤的,不論你後面怎麼改,底子都不是好。之所以會遇到丟雙引號,就是因爲解析的時候出錯了,轉換格式的時候雙引就被當作非acsii字符刪掉了。而且還是隨機的。根本無規律可循!!!

終於明白爲什麼叫悟空了,腦子空了才能悟出東西來。


因爲一直糾結爲什麼在eclipse下就能正常運行的問題,於是搜索了一下如何像eclipse一樣強制按照UTF-8編碼讀取文件。

萬萬沒想到,最後XX還是XXX了(好像就是這麼說的吧,每集必備的臺詞)

萬萬沒想到,最後問題還是被我解決了。

在可執行jar包前加上-Dfile.encoding=UTF-8之後,終於把所有文件全部解析成功。


長吁了一口氣,發個短信告慰了下陪老婆的大牛這個問題我解決了,哇咔咔咔。

然後被大牛加了個需求(他是這活的主要負責人,我來幫忙的幹活),把這個參數寫到項目裏,免得別人每次用還要重複輸入。


好嘞!

心想趕緊幹完這票,保存下今天的戰果上傳,然後發個週報給大boss,然後回家給加班的老婆做飯等老婆回家,一起吃飯看爸爸去哪兒。。。。


然後又經過了1個小時。。。


我擦,這尼瑪不管用啊。

理論上(自認爲是這樣的,沒有科學依據,大家手下留情)設置一個全局的file.encoding不就行了?

System.setProperty("file.encoding","UTF-8");

然後設置,發現運行還是出錯,沒道理啊。

然後這時候大牛來了,我說有個問題。。

大牛說你今天的問題權已經用完了,下週吧,呵呵呵呵。。。

我勒個去,心說我自己弄。。。哼哼哼哼


大牛過來了。

大牛說:你把這個加上不就行了(就我加的那個。。。)

然後我把功能的部分註釋掉,只留了編碼打印的代碼給他看。

我說不行啊,你看加了這行之後,執行jar包,打印編碼,還是默認的GBK。

等等。。

怎麼可以了?變成UTF-8了。。。(是因爲之前我使用eclipse運行的時候沒有設置這個參數,直接從系統獲取然後打印的,由於eclipse已經設置了默認是utf-8,所以在eclipse中自然就是UTF-8。但是jar包執行的時候還是系統默認的GBK. 當時我演示的時候把這個參數加上了,當然就起作用了)

好吧。待我把功能代碼恢復下,然後看結果如何。。。


嗯???!!!改成utf-8了還是不工作啊,不工作。。

然後我又把-Dfile.encoding=UTF-8加上之後,又完美的工作了,工作了,了。。。


大牛看了看,2秒之後說,回家吧,我媳婦樓下等我呢。閃之。。。


暗暗鄙視之。。。。



然後收拾東西準備回家。。。


想到下週還要解決這個問題,然後搜索了下,獲得瞭如上的參閱鏈接,晚點自己研究下。

然後寫下了這篇曲折又有趣的debug經歷。

你看到這篇文章發表的時間就是我下班的時間。


嗯,一天的時間+3個小時都沒有搞定的問題。


嗯。。還在等老婆中,因爲她已經下班回家在路上了。。。


在辦公室。TT


參考關於file.encoding=UTF-8的資料

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

http://yang3wei.github.io/blog/2013/02/10/java-dfile-dot-encoding-equals-utf-8-gan-diao-luan-ma/


最後公佈答案

問題: 使用java如何判斷在一個字符串裏,特定單詞的數量

答案:使用split

因爲java的split是支持正則的(不清楚哪個版本有的這個特性),所以我們可以講我們需要查找的單詞使用正則來進行匹配,兼容大小寫的哦:)

split之後判斷數組長度,將長度減1就是答案了

想到這個是因爲我要判斷這一行裏引號的數量是不是偶數對。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章