2010-06-22 153 views
5

我寫了下面的方法來查看特定文件是否僅包含ASCII文本字符或控制字符。你能否看一下這段代碼,提出改進建議並指出疏漏?如何檢查文件是否是二進制文件?

的邏輯如下:「如果第一個500個字節的文件中包含5個或更多的控制字符 - 報告爲二進制文件」

謝謝。

public boolean isAsciiText(String fileName) throws IOException { 

    InputStream in = new FileInputStream(fileName); 
    byte[] bytes = new byte[500]; 

    in.read(bytes, 0, bytes.length); 
    int x = 0; 
    short bin = 0; 

    for (byte thisByte : bytes) { 
     char it = (char) thisByte; 
     if (!Character.isWhitespace(it) && Character.isISOControl(it)) { 

      bin++; 
     } 
     if (bin >= 5) { 
      return false; 
     } 
     x++; 
    } 
    in.close(); 
    return true; 
} 

回答

3

既然你把這個類叫做isASCIIText,你就知道你在找什麼。換句話說,它不是「isTextInCurrentLocaleEncoding」。因此,你可以更準確,:

if (thisByte < 32 || thisByte > 127) bin++; 

編輯,時間長了以後 —它指出了一個註釋,這個簡單的檢查將通過與大量的換行開始的文本文件被絆倒。最好使用「OK」字節的表格,並且包含可打印字符(包括回車符,換行符和製表符,可能還有換頁符,儘管我不認爲許多現代文檔使用這些字符),然後檢查桌子。

+0

當這個算法將包含「this \ r \ nis \ r \ nonly \ r \ ntext」的文件分類爲二進制文件時,這被標記爲正確答案是悲劇。 – Ingo 2013-12-08 23:30:09

+1

@Ingo true;最好檢查一些控制字符與非控制字符的比例,並檢查文本中常見的控制字符等特殊情況。當我輸入這個答案時,我很年輕:) – Pointy 2013-12-08 23:41:53

3

x似乎沒有做任何事情。

如果是什麼文件小於500個字節?

一些二進制文件有一個情況下,你可以對文件的前N個字節的報頭包含一些數據,對於一個應用程序,但該庫中的二進制是不關心是非常有用的。您可以在前導碼中輕鬆使用500+字節的ASCII碼,接下來是千兆字節的二進制數據。

應該處理異常,如果該文件無法打開或讀取等

1

我注意到的第一件事情 - 無關的實際問題,但你應該在finally塊被關閉的輸入流,以確保它總是完成。通常這僅僅處理異常,但在你的情況下,當返回false時甚至不會關閉文件流。從

旁白,爲什麼比較ISO控制字符?這不是一個「二進制」文件,這是一個「包含5個或更多控制字符的文件」。一個更好的方式來處理這種情況在我看來,將是反轉的檢查 - 寫isAsciiText功能,而不是其聲稱該文件中的所有字符(或頭500個字節,如果你願意的話)是一組字節那就是已知不錯

理論上,只檢查一個文件的前幾百字節可能會讓你陷入麻煩,如果它是一個排序的複合文件(例如帶嵌入圖片的文本),但實際上我懷疑每個這樣的文件都會有二進制標題數據在開始時你可能確定。

0
  1. 您忽略了read()返回的內容,如果文件短於500字節,該怎麼辦?
  2. 當你返回false時,你不關閉文件。
  3. 當轉換字節爲char,你認爲你的文件是7位ASCII。
0

這不會與JDK安裝工作包Linux或Solaris。他們有一個shell腳本啓動,然後是一個雙數據塊。

爲什麼不使用jMimeMagic(http://http://sourceforge.net/projects/jmimemagic/)這樣的庫檢查MIME類型,並基於mimetype如何處理該文件。

3
  1. 嚴重失敗如果文件大小小於500個字節

  2. char it = (char) thisByte;概念性可疑,它混合字節和字符的概念,即。默認假設編碼是一個字節=一個字符(它們,它不包括Unicode編碼)。特別是,如果文件是UTF-16編碼,則失敗。

  3. 循環內的回報(稍差的練習IMO)忘記關閉文件。

相關問題