2017-06-20 117 views
0

民間,從文件讀取時字符被丟棄?

我有一些非ASCII輸入,我需要使用分隔符解析。如果我以TextPad二進制模式打開輸入文件,我可以看到分隔符實際上是一個三字符的十六進制值C3,83和3F序列。這個中間人物(「不要在這裏」控制角色)讓我感到悲傷。當我在java中將文件讀入字符串時,該字符似乎被刪除。

實施例的代碼(僅存在1的文件中的行:)

String escapedDelimiter = args[0]; 
String delimiter = StringEscapeUtils.unescapeJava(escapedDelimiter); 
String s = null; 

try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(args[1]), Charset.forName(args[2])))) { 
    s = br.readLine(); 
} 

System.out.println(delimiter); 
System.out.println("delimiter length: " + delimiter.length()); 
System.out.println(s); 
System.out.println("s length: " + s.length()); 

int i = s.indexOf(delimiter); 
System.out.println(i); 

輸出:

Ã?

定界符長度:?3

ÃHelloÃWorldÃ?

小號長度:16

-1

定界符長度是正確的,但小號長度不是。該文件包含19個字節。來自3個分隔符的每個字符中的一個字符丟失。

硬編碼像這樣的字符串的作品,但我需要從文件中讀取輸入:

String s = "\u00C3\u0083\u003FHelloÃ\u0083?World"; 

有趣的是,在第3鍵入轉義字符,複製後和粘貼他們的「Hello」導致他們被Ã\ u0083?取代。這是造成麻煩的中間角色。

有人知道發生了什麼事嗎?

謝謝

+2

那麼你試圖編碼?我的猜測是,它不是正確的文件編碼... –

+0

如果文件是UTF-8,那麼該分隔符是* 2 *個字符長,而不是3.「Ã?」是0xc3 0x83 0x3f的UTF-8解碼版本。這是一個很奇怪的分隔符,雖然... –

+1

「?」有時用於靜默刪除數據([替換字符策略](https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#decode-java.nio.ByteBuffer- ))當用沒有寫入的編碼讀取文本時。默認行爲取決於平臺,實際行爲取決於編碼。如果「?」這裏看起來不對,可能是輸入文件已被上游進程損壞。在任何情況下,您都必須查看上游以瞭解用於讀取任何文本文件的字符編碼。 –

回答

0

我會讀取該文件作爲字節數組,而不是尋找你想要的確切分隔符。然後將字節[]轉換爲字符串。

如果性能/內存使用率不是問題,我會使用Commons IO來讀取字節。

https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/FileUtils.html#readFileToByteArray(java.io.File)

然後搜索你想要的圖案陣列。最後,將其他塊轉換爲String。

String value = new String(myBytes) ; 

如果你擔心性能/內存,讀取線性使用字節:

(byte) InputStream.read() 

搜索您的分隔符,你繼續。

+1

這似乎是一個很好的策略,但'new String(myBytes)'將跨系統,用戶和時間使用不同的字符編碼 - 很少有人想要的。 –

+1

@TomBlodget提供了很好的建議。確保使用String(byte []字節,Charset字符集)構造函數。 –

0

在您的代碼new InputStreamReader(new FileInputStream(args[1]), Charset.forName(args[2]))替換Charset.forName(args[2])與硬編碼StandardCharsets.UTF_8,看看它是否有幫助。還讀取它作爲字節和字節工作可能會有所幫助。還有另一個工具可以幫助你 - 我寫了一個實用工具,將任何字符串轉換爲Unicode序列,反之亦然。玩這種奇怪的例子,並將其轉換回來,有時可能會幫助你理解這個問題。這裏是一篇文章的鏈接,該文章解釋了何處獲得開放源代碼庫以及如何使用它:Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison。尋找段落「字符串的Unicode轉換器