1

ディレクトリ内のすべての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

これは私がディレクトリ上で繰り返し使用しているものです:

  import java.io.File;

  ...

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

これどうやってするの?RARアーカイブかどうかを検出する必要があります。そうでない場合は、それを使用してください。もしそうなら、それがアーカイブの最初の部分であるかどうかを確認する必要があります。はいの場合は何でもし、そうでない場合は無視します。

ありがとう

4

4 に答える 4

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;
     }

 }

公式のRARヘッダー仕様を使用しました。これを実装してバイトを解析するために、私はここでの議論に従いました:

バイナリファイルから16進値を読み取り、ビットフラグ値を含むいくつかのバイトを解読するにはどうすればよいですか?

于 2012-07-04T10:35:34.897 に答える
2

解決策を見つけることの難しさは、.rarアーカイブが複数のファイルにまたがっている場合、設定された命名手法がないことです。さらに、ユーザーが、スパンされたRARパーツの1つであるかのように名前が付けられたランダムファイルを作成することを妨げるものは何もありません。これを判断する唯一の適切な方法は、疑わしい各ファイルの内容を実際に読み取り、これがスパンされたrarファイルの続きであるかどうかを確認することです。複雑なことは別として、これも容認できないほど遅いでしょう。

ただし、ほとんどの場合、分割されたファイルには、継続として(正確に2桁)、または最初のファイル(XXXは1から始まり、最大数になります)のいずれかfile.rarで名前が付けられます。したがって、以下のようなものを使用して、これら2つのケースをキャッチしてみることができます。file.rXXfile.partXXX.rarfile.part1.rarFilenameFilter

この方法の欠点は、たとえば、ファイルにランダムな名前が付けられた場合にファイルが破棄されることです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
    }
}
于 2012-07-03T15:20:02.213 に答える
0

ファイル名がendsWith( "。rar")であるかどうかを確認し、一意性を確保するためにセットに入れます

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

if(fileName.endsWith(".rar")){
    set.add(fileName);
}
于 2012-07-03T15:02:54.250 に答える
0

ステップ1:File.listFile(FileFilter)あなたの友達です。正しく実装すると、RARとスパニングファイルのみが提供されます。

ステップ2:上記で提案したように、すべての名前のプレフィックスを個別のコレクションに収集します。

于 2012-07-03T15:18:55.327 に答える