18

SVN の下にディレクトリ ツリーを作成するコードの一部の統合テストに取り組んでいます。これには、ディレクトリ構造とその中のファイルが期待どおりかどうかをテストする必要があります。

一方では、必要なファイルを含む予想されるディレクトリ ツリーがあり、他方では、SVN からのファイルのエクスポートがあります (ノイズsvn exportsvn co避けることをお勧めします)。.svn

しかし、2 つのディレクトリ ツリーをアサートできるライブラリはありますか? 私が念頭に置いている最後の手段は、自分で繰り返し比較を行うことです。

基本的に、2 つのディレクトリを受け入れて、それらが等しいかどうかを教えてくれる API を探しています。

ライン上の何か

boolean areDirectoriesEqual(File dir1, File dir2)
4

9 に答える 9

3

私は同じ問題を抱えていて、Patrick と Lorenzo Dematté に従って、自分に合った解決策を見つけました。次のコードは、フォルダーをウォークスルーし、次のようにします。

  • サブフォルダーごとに、ファイルリストが同じかどうかを確認します
  • 各ファイルの内容を比較します(私の場合、csvファイルを含む2つのフォルダーを比較する必要があります)

Linuxでテストしました。

  private static void verifyDirsAreEqual(File expected, File generated) 
                throws IOException {

    // Checks parameters 
    assertTrue("Generated Folder doesn't exist: " + generated,generated.exists());
    assertTrue("Generated is not a folder?!?!: " + generated,generated.isDirectory());

    assertTrue("Expected Folder doesn't exist: " + expected,expected.exists());
    assertTrue("Expected is not a folder?!?!: " + expected,expected.isDirectory());     

    Files.walkFileTree(expected.toPath(), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir,
                BasicFileAttributes attrs)
                  throws IOException {
            FileVisitResult result = super.preVisitDirectory(dir, attrs);

            // get the relative file name from path "expected"
            Path relativize = expected.toPath().relativize(dir);
            // construct the path for the counterpart file in "generated"
            File otherDir = generated.toPath().resolve(relativize).toFile();
            log.debug("=== preVisitDirectory === compare " + dir + " to " + otherDir);
            assertEquals("Folders doesn't contain same file!?!?",
                    Arrays.toString(dir.toFile().list()),
                    Arrays.toString(otherDir.list()));
            return result;
        }
        @Override
        public FileVisitResult visitFile(Path file,
                BasicFileAttributes attrs)
                throws IOException {
            FileVisitResult result = super.visitFile(file, attrs);

            // get the relative file name from path "expected"
            Path relativize = expected.toPath().relativize(file);
            // construct the path for the counterpart file in "generated"
            File fileInOther = generated.toPath().resolve(relativize).toFile();
            log.debug("=== comparing: " + file + " to " + fileInOther);
            String expectedContents = FileUtils.readFileToString(file.toFile());
            String generatedContents = FileUtils.readFileToString(fileInOther);
            assertEquals("("+fileInOther+")  csv standard doesn't match expected ("+file+")!", expectedContents, generatedContents);                    
            return result;
        }
    });
}
于 2016-11-24T13:35:11.213 に答える
3

私はareDirsEqualライブラリを認識していません。私が考えることができる最も近いものは Commons の listFiles メソッドFileUtilsです。

結果のコレクションを に入れるHashSetと、2 つのセットを効率的に比較できるはずです。そして、それは 2 行で、場合によっては 1 行で行うこともできます。

この行の何か:

public static boolean areDirsEqual(File dir, File dir2) {
  return (new HashSet<File>(FileUtils.listFiles(dir1,..))).
          containsAll(FileUtils.listFiles(dir2, ..))
}
于 2013-01-25T13:27:59.460 に答える
1

わかりましたので、それを行う準備ができているコードを知りませんし、検索も役に立ちませんでした。だからここに私がそれを実装する方法があります

  1. すべてのフォルダーとファイルに対して再帰的に反復する
  2. ハッシュセットのルートからの相対パスですべてのファイル名を保存します。相対パスはキー/値です
  3. 2 番目のディレクトリ構造を再帰的に反復し、ハッシュ内のキーと一致するように各パスから を作成します (フォルダー/ファイルが存在する場合)。

ツリーを変更済み/未変更としてマークしたいだけの場合は、各ファイルのハッシュを保存できます。次に、各ファイルの内容のハッシュがハッシュマップの値であるハッシュセットの代わりにハッシュマップが必要です

お役に立てれば

于 2013-01-25T13:16:46.007 に答える
-5
import java.io.File;

/**
 * 
 * FileUtils is a collection of routines for common file system operations.
 * 
 * @author Dan Jemiolo (danj)
 * 
 */

public final class FileUtils {

  /**
   * 
   * This is a convenience method that calls find(File, String, boolean) with
   * the last parameter set to "false" (does not match directories).
   * 
   * @see #find(File, String, boolean)
   * 
   */
  public static File find(File contextRoot, String fileName) {
    return find(contextRoot, fileName, false);
  }

  /**
   * 
   * Searches through the directory tree under the given context directory and
   * finds the first file that matches the file name. If the third parameter is
   * true, the method will also try to match directories, not just "regular"
   * files.
   * 
   * @param contextRoot
   *          The directory to start the search from.
   * 
   * @param fileName
   *          The name of the file (or directory) to search for.
   * 
   * @param matchDirectories
   *          True if the method should try and match the name against directory
   *          names, not just file names.
   * 
   * @return The java.io.File representing the <em>first</em> file or
   *         directory with the given name, or null if it was not found.
   * 
   */
  public static File find(File contextRoot, String fileName, boolean matchDirectories) {
    if (contextRoot == null)
      throw new NullPointerException("NullContextRoot");

    if (fileName == null)
      throw new NullPointerException("NullFileName");

    if (!contextRoot.isDirectory()) {
      Object[] filler = { contextRoot.getAbsolutePath() };
      String message = "NotDirectory";
      throw new IllegalArgumentException(message);
    }

    File[] files = contextRoot.listFiles();

    //
    // for all children of the current directory...
    //
    for (int n = 0; n < files.length; ++n) {
      String nextName = files[n].getName();

      //
      // if we find a directory, there are two possibilities:
      //
      // 1. the names match, AND we are told to match directories.
      // in this case we're done
      //
      // 2. not told to match directories, so recurse
      //
      if (files[n].isDirectory()) {
        if (nextName.equals(fileName) && matchDirectories)
          return files[n];

        File match = find(files[n], fileName);

        if (match != null)
          return match;
      }

      //
      // in the case of regular files, just check the names
      //
      else if (nextName.equals(fileName))
        return files[n];
    }

    return null;
  }

}
于 2013-01-25T13:00:00.183 に答える