【问题标题】:Compare file extension to file header比较文件扩展名和文件头
【发布时间】:2011-04-08 17:41:22
【问题描述】:

我开始设计一个应用程序,它会在一定程度上运行文件目录并将它们的扩展名与文件头进行比较。

对于解决此问题的最佳方法,有人有任何建议吗?我知道我可以简单地拥有一个包含文件头签名的查找表。例如,JPEG: \xFF\xD8\xFF\xE0

我希望可能有更简单的方法。

提前感谢您的帮助。

【问题讨论】:

  • 这个目录下是否有各种格式的文件,还是只有JPEG?
  • 我只会进一步处理大约 20 种文件类型 .doc、.xls、.pdf 等。

标签: java


【解决方案1】:

恐怕它必须比这更复杂。并不是每一种文件类型都有一个文件头,有些文件(比如 RAR)在结尾而不是开头都有其特有的数据结构。

您可能想看看 Unix file 命令,它执行相同的工作:

【讨论】:

    【解决方案2】:

    如果您不需要对这些值进行繁琐的工作(并且您没有 linux),您可以简单地使用一个外部程序,例如 TrID,它可以为您做这件事。

    也许你可以只处理它的输出而不关心自己做。无论如何,如果你只有大约 20 种文件,你必须管理一个简单的查找表(例如。HashMap<String,byte[]>)没有那么糟糕。当然,这仅在所需的文件格式具有幻数时才有效,否则您只能靠自己(或使用外部程序)。

    【讨论】:

      【解决方案3】:

      由于某些文件类型缺少重要标头的问题(感谢@Michael),我将创建一个扩展映射到一种类型检查器,其中包含一个简单的 API,例如

      public interface TypeCheck throws IOException {
        public boolean isValid(InputStream data);
      }
      

      现在你可以编写类似的代码

      File toBeTested = ...;
      Map<String,TypeCheck> typeCheckByExtension = ...;
      TypeCheck check = typeCheckByExtension.get(getExtension(toBeTested.getName()));
      if (check != null) {
        InputStream in = new FileInputStream(toBeTested);
        if (check.isValid(in)) {
          // process valid file
        } else {
          // process invalid file
        }
        in.close();
      } else {
        // process unknown file
      }
      

      例如,JPEG 的标头检查可能看起来像

      public class JpegTypeCheck implements TypeCheck {
        private static final byte[] HEADER = new byte[] {0xFF, 0xD8, 0xFF, 0xE0};
      
        public boolean isValid(InputStream data) throws IOException {
          byte[] header = new byte[4];
          return data.read(header) == 4 && Arrays.equals(header, HEADER);
        }
      }
      

      对于没有重要标头的其他类型,您可以完全实现其他类型检查。

      【讨论】:

        【解决方案4】:

        您可以提取每个文件的 mime 类型并将其与 mimetype/extension 的映射进行比较(Map&lt;String, List&lt;String&gt;&gt;,第一个 String 是 mime 类型,第二个是有效扩展名列表)。


        资源:

        关于同一主题:

        【讨论】:

          【解决方案5】:

          你可以知道使用 apache tika 读取头文件的文件类型。
          以下代码需要 apache tika jar。

          InputStream is = MainApp.class.getResourceAsStream("/NetFx20SP1_x64.txt");
          BufferedInputStream bis = new BufferedInputStream(is);
          
          AutoDetectParser parser = new AutoDetectParser();
          Detector detector = parser.getDetector();
          Metadata md = new Metadata();
          md.add(Metadata.RESOURCE_NAME_KEY,MainApp.class.getResource("/NetFx20SP1_x64.txt").getPath());
          MediaType mediaType = detector.detect(bis, md);
          
          System.out.println("MIMe Type of File : " + mediaType.toString());
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-04-30
            • 2015-04-25
            • 2012-10-19
            • 2011-06-18
            • 1970-01-01
            • 1970-01-01
            • 2021-07-01
            • 2011-05-17
            相关资源
            最近更新 更多