2010-12-14 181 views
6

所有,java.net.URLConnection.guessContentTypeFromStream和純文本/

我試圖找出純文本文件與Mac行尾和,一個InputStream裏面,默默地將它們轉換爲Windows或Linux行尾(重要部分是LF字符,真的)。具體來說,我正在處理幾個採用InputStream的API,並將其鎖定爲\ n作爲換行符。

有時,我會得到二進制文件。很顯然,一個非文本類型的文件不應該進行這種替換,因爲恰好相應於\ r的值不會在後面悄悄地跟隨\ n而不會嚴重損壞。

我正在嘗試使用java.net.URLConnection.guessContentTypeFromStream,並且只在類型爲text/plain時才執行endline轉換。不幸的是,"text/plain"似乎不在其返回值的範圍內;我所得到的是我的平面文本文件的null,假設所有無法識別的文件都可以修改,可能並不安全。

我可以用更好的庫(最好在公共Maven存儲庫和開源中)來做到這一點?或者,我怎麼能guessContentTypeFromStream爲我工作?我知道我正在描述一個固有的危險應用程序,沒有解決方案可能是完美的,但是我應該把「空白」看作是「文本/純文本」,我只需要自己編寫更多的代碼來尋找證據證明它不是「T?

+2

+1爲「色域」。 – skaffman 2010-12-14 20:32:24

回答

2

在我看來,你問的是確定一個文件是否是文本文件。鑑於此,有一個解決方案here似乎正確:

誠然,他是在談論UNIX,bash和perl的,但概念是相同的:

除非你檢查0​​文件的每個字節,你不會100%獲得這個 。有一個很大的性能 檢查每個字節。但 經過一些實驗後,我決定在 算法適合我。 I 檢查第一行並聲明 文件是二進制文件,如果我遇到一個非文本字節即使是 。這似乎有點鬆懈,我知道,但我似乎脫掉了 與它。

編輯#1:
擴大這種類型的解決方案,這似乎是一個合理的辦法是,以確保文件未包含非ASCII字符(除非你正在處理的是非文件 - 英語......那是另一種解決方案)。這可以通過檢查來完成,如果文件內容作爲一個字符串不匹配這樣的:

// -- uses commons-io 
String fileAsString = FileUtils.readFileToString(new File("file-name-here")); 
boolean isTextualFile = fileAsString.matches(".*\\p{ASCII}+.*"); 

編輯#2
你可能想試試這個作爲你的正則表達式,或接近它。雖然,我承認它可能會使用一些提煉。

".*(?:\\p{Print}|\\p{Space})+.*" 
+0

我打算使用類似於如果所有其他都失敗的方法,除了比正則表達式少得多的優雅。 (逐字節檢查,這裏我來了!)而不是一條線,我可能會使用一個固定的字符數,主要是不會冒我的BufferedReader上的標記(...)位置的溢出風險。雖然這是一個令人頭痛的角色類,對於那些不會說Perl的人來說,Java表單是什麼? – 2010-12-14 20:43:21

+1

我不知道這是如何作用於Unicode文本文件。 – BalusC 2010-12-14 21:09:45

+0

指定的正則表達式有些過於寬容,但是取出了前導和尾隨。*(我們想讓課堂外的人物失去資格!)做到了。謝謝。 – 2010-12-14 23:21:01