Java遍历所有文件,只遍历目录中唯一的RAR压缩文件

时间:2012-07-03 14:56:37

标签: java

如何遍历目录中的所有RAR压缩文件。我知道如何迭代目录中的文件,但我只对RAR档案感兴趣。如果它们是带有扩展名.rar的简单RAR存档,那么这不是问题,但我的目录可以有多个跨区存档,我只想要集合中的第一个/主要卷。我还想在目录中包含其他文件:

以下是示例目录的内容:

  • file.txt
  • somefile.zip
  • hello.rar
  • test.part1.rar
  • test.part2.rar
  • example.rar
  • example.r00

结果:

  • file.txt
  • somefile.zip
  • hello.rar
  • test.part1.rar
  • example.rar

这就是我在目录上使用ti迭代的内容:

  import java.io.File;

  ...

  for (File child : (new File(myDirectoryPath)).listFiles()) {
    if (!child.isDirectory()) {
      //Do something with the file
    }
  }

我该怎么做?我需要检测它是否是RAR存档。如果不是,请使用它。如果是,我需要检查它是否是存档的第一部分。如果是,做任何事,否则忽略它。

由于

4 个答案:

答案 0 :(得分:2)

找到解决方案的困难在于.rar存档跨越多个文件时没有设置命名技术。此外,没有任何东西阻止用户创建一个名为的随机文件,就好像它是一个跨越的rar部分。确定这一点的唯一正确方法是实际读取每个可疑文件的内容,并查看这是否是跨区rar文件的延续。除了复杂,这也会慢得令人无法接受。

但是在大​​多数情况下,拆分文件的名称为file.rarfile.rXX(正好为2位数)作为续点,或file.partXXX.rar,第一个文件为file.part1.rar( XXX从1开始,然后转到最大数量)。因此,您可以尝试使用FilenameFilter来解决这两种情况,如下所示。

这种方法的缺点是,如果文件碰巧被随机命名,它会丢弃文件,例如somefile.part2.rarotherfile.r03,但希望这对大多数情况有帮助。

for (File child : (new File(myDirectoryPath)).listFiles(new FilenameFilter() {
    private Pattern p1 = null;
    private Pattern p2 = null;
    public boolean accept(File dir, String name) {

        name = name.toLowerCase();

        if(p1 == null) {
            p1 = Pattern.compile("\\.r\\d\\d");
            p2 = Pattern.compile("\\.part\\d+\\.rar");
        }

        if(name.endsWith(".part1.rar")) {
            return true;
        }
        else if(p2.matcher(name).matches()) {
            return false;
        }
        else {
            return !p1.matcher(name).matches();
        }
    }
}) {
    if (!child.isDirectory()) {
      //Do something with the file
    }
}

答案 1 :(得分:2)

我已经编写了这段代码来识别RAR档案,我只考虑跨越档案的第一卷并省略其他档案。

/**
 * Checks whether a file is an archive
 *
 * @param    filFile        the file to checks
 * @retuns                  a bollean value indicating the result
 */
 public static Boolean isArchive(File filFile) {  

     try {

         byte[] bytSignature = new byte[] {0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
         FileInputStream fisFileInputStream = new FileInputStream(filFile);

         byte[] bytHeader = new byte[20];
         fisFileInputStream.read(bytHeader);

         Short shoFlags = (short) (((bytHeader[10]&0xFF)<<8) | (bytHeader[11]&0xFF));

         //Check if is an archive
         if (Arrays.equals(Arrays.copyOfRange(bytHeader, 0, 7), bytSignature)) {
             //Check if is a spanned archive
             if ((shoFlags & 0x0100) != 0) {
                 //Check if it the first part of a spanned archive
                 if ((shoFlags & 0x0001) != 0) {
                     return true;
                 } else {
                     return false;
                 }
             } else {
                 return true;
             }
         } else {
             return true;
         }

     } catch (Exception e) {
         return false;
     }

 }

我使用了official RAR header specifications。为了实现这一点并解析字节,我在这里进行了讨论:

How do I read in hex values from a binary file and decipher some bytes containing bitflag values?

答案 2 :(得分:0)

检查你的文件名是否以(“。rar”)结尾并将其放入一套以确保唯一性

Set<String> fileSet=new HashSet<String>();

if(fileName.endsWith(".rar")){
    set.add(fileName);
}

答案 3 :(得分:0)

第1步:File.listFile(FileFilter)是你的朋友。正确实现,只会为您提供RAR和跨越文件。

步骤2:收集上述不同集合中所有名称的前缀。