如何知道文件是否是文本呈现? (JAVA)

时间:2011-11-17 07:15:58

标签: java file-io

如何在运行时知道指定文件夹中的文件是否为文本呈现? (即可以显示为文本的csv,html等文件)

我不想通过扩展匹配(通过检查.txt,.html扩展等)来做到这一点。

假设有一个jpg文件,我故意将扩展名重命名为.txt,而java代码应该能够检测到这个文件(虽然带有.txt extn)不能呈现为文本。

我怎样才能在java中实现这个目标?

6 个答案:

答案 0 :(得分:1)

实现一个启发式匹配器,扫描文件以查找已知签名。

一个典型的例子是file命令:http://en.wikipedia.org/wiki/File_(command)和libmagic库。

Java中有几种变体,例如Tika:http://tika.apache.org/

答案 1 :(得分:1)

您可以通过扫描文件并使用Character.html#isISOControl来猜测类型,以检查是否包含不可打印的字符。

二进制文件通常包含通常包含控制字符的标题,请参阅list of File Signatures isISOControl将检测到它们中的大多数。

答案 2 :(得分:0)

我认为没有100%万无一失的方法可以做到这一点,因为这是一个意见问题,重要的是“可以显示为文本”...但如果你可以将它限制为英文文本,你可以检查文件的字节,如果大多数或所有字节值都在32到126(十进制无符号)的范围内,那么很可能是vanilla ASCII text

答案 3 :(得分:0)

这需要某种统计模式匹配。例如,如果您只使用英语,则可以检查前100个字符中出现的“外来”字符数。这应该让你很好地了解这是否是一个文本文件。如果遇到太多不是a..zA..Z0..9 [punctutation]的字符,那么你可以猜测它不是文本。使用英语文件和可以使用ASCII字符列表表达的语言,您应该相对安全。

当你开始使用外语时,这当然会在窗口中出现,其中某些字符可能看起来像是特殊字符,但仅限于那些不会说这种语言的人。

另一种方法是使用文件标记(如Java中的类文件以特定标头开头),并将文件中的值与标头库进行比较。它既麻烦又容易出错,因为您可能没有记录文件,因此可能认为它不是文本文件。

答案 4 :(得分: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);
            }
        }
    }
}

答案 5 :(得分:-1)

您可以维护一个可接受的Mime类型列表,然后获取您正在阅读的Mime Type文件。如果它符合要好。

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