2011-11-17 141 views
2

如何知道運行時指定文件夾中的文件是否爲文本渲染? (即像csv,html等可以顯示爲文本的文件)如何知道文件是否爲文本渲染? (Java)

我不想通過擴展匹配(通過檢查.txt,.html擴展等)來做到這一點。

假設如果有一個jpg文件,我故意將擴展名重命名爲.txt,而且java代碼應該能夠檢測到該文件(儘管帶有.txt extn)不能被渲染爲文本。

我該如何在java中實現這個功能?

回答

1

您可以通過掃描該文件並使用Character.html#isISOControl來檢查是否包含不可打印的字符,從而猜出該類型。

二進制文件通常包含通常包含控制字符的標頭,請參閱此list of File Signatures其中大多數將由isISOControl檢測到。

0

我不認爲這是一個100%萬無一失的方法來做到這一點,因爲這是一個見仁見智什麼算是「可以顯示爲文本「...但如果您可以將其限制爲英文文本,則可以檢查文件的字節,並且如果大部分或全部字節值在32到126(十進制無符號)的範圍內,則很可能是vanilla ASCII text

+0

不要忘記CR \ LF ;-) – Jimmy

+0

是的,也是標籤! –

0

這是要求某種統計模式匹配。例如,如果您只使用英文,請檢查前100個字符中出現多少「外來」字符。這應該給你一個很好的主意,看它是否是文本文檔。如果遇到太多不是a..zA..Z0..9 [punctutation]的字符,則可以猜測它不是文本。使用英文文件和主要用ASCII字符列表表示的語言,你應該相對安全。

當你開始使用外國語言的時候,這些當然會走出窗口,其中一些字符可能看起來像是特殊字符,但只對不會說這種語言的人有用。

另一種選擇是使用文件標記(就像在Java中,一個類文件以一個特定的頭文件開頭),並將文件中的值與頭文件庫進行比較。它也很麻煩,也容易出錯,因爲你可能沒有記錄文件,因此可能認爲它是一個文本文件。

-1

您可以維護可接受的MIME類型的列表,然後獲取您正在閱讀的文件的MIME類型。如果它匹配很好去。

import javax.activation.MimetypesFileTypeMap; 
import java.io.File; 

class GetMimeType { 
    public static void main(String args[]) { 
    File f = new File("gumby.gif"); 
    System.out.println("Mime Type of " + f.getName() + " is " + 
         new MimetypesFileTypeMap().getContentType(f)); 
    // expected output : 
    // "Mime Type of gumby.gif is image/gif" 
    } 
} 

http://www.rgagnon.com/javadetails/java-0487.html

+0

這將通過擴展。 MIME類型不是從內容推斷的。 –

+0

'MimetypesFileTypeMap'不好!它怎麼能有一個不存在的文件的mimetype?這意味着它基本上檢查擴展名。 (不是我的downvote) – Mob

+0

@YannRamin是的我的不好,只是測試了代碼,多數民衆贊成在不好...感謝指出。 – Zohaib

0

使用的a Character#isISOControl是一件好事。你也應該考慮編碼(p.ex.UTF-8)。在這裏我的功能:

/** 
* Test is a file is a text file. It is the case only if it has no well-known control characters. 
* (see {@link Character#isISOControl(int)}) 
* @param file 
* @return 
* @throws IOException 
*/ 
public static boolean isTextFile (final File file) throws IOException 
{ 
    BufferedInputStream is = null; 
    try 
    { 
     final BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-16")); 

     boolean isText; 
     int read; 
     do 
     { 
      read = in.read(); 
      isText = read == -1; 
      isText |= read == 13; // newline 
      isText |= read == 10; // newline 
      isText |= read == 9; // tab 
      isText |= !Character.isISOControl(read); 
     } 
     while (isText && read != -1); 

     return isText; 
    } 
    finally { 
     if (is != null) 
     { 
      try 
      { 
       is.close(); 
      } 
      catch (IOException e) 
      { 
       throw new Error(e); 
      } 
     } 
    } 
}