2010-06-22 201 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)忘记关闭文件。

相关问题