Files.walkFileTree traverses directory files

java.nio.file.Files.walkFileTreeyesJDK7New static tool method.

Files.walkFileTree Introduction to the principle of

static Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor) throws IOException;

static Path walkFileTree(Path start, FileVisitor<? super Path> visitor) throws IOException;

Parameter list:

  • Start path of java.nio.file.Path start traversal
  • Set < Java. NiO. File. Filevisitoption > Options traversal options
  • int maxDepth traversal depth
  • Behavior controller in java.nio.file.file visitor <? Super Path > visitor traversal

Traversal behavior controller FileVisitor

The java.nio.file.FileVisitor interface contains four methods, involving several important step nodes in the traversal process. In general, SimpleFileVisitor is used to simplify the operation.

public interface FileVisitor<T> {

    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
        throws IOException;

    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
        throws IOException;

    FileVisitResult visitFileFailed(T file, IOException exc)
        throws IOException;

    FileVisitResult postVisitDirectory(T dir, IOException exc)
        throws IOException;
}
  • preVisitDirectory access a directory and call it before entering.
  • postVisitDirectory all nodes of a directory are called after being accessed. When traversing, skip the same level directory or an error occurs. Exception will be passed to this method.
  • Called when the visitFile file is accessed. The file properties of the file are passed to this method
  • visitFileFailed this method is called when the file cannot be accessed. Exception is passed to this method.

Traversal behavior result FileVisitResult

public enum FileVisitResult {
    CONTINUE,
    TERMINATE,
    SKIP_SUBTREE,
    SKIP_SIBLINGS;
}
  • CONTINUE traversal
  • SKIP_SIBLINGS continues to traverse, but ignores all siblings of the current node and directly returns to the previous layer to continue to traverse
  • Skip? Continue to traverse, but ignore the subdirectory, but the sub file will still access
  • TERMINATE terminate traversal

Find the specified file

Using startsWith, endsWith and other methods provided by java.nio.file.Path, we need to pay special attention to: matching the complete content of the path node, not the string.

For example, / usr/web/bbf.jar

Path path = Paths.get("/usr/web/bbf.jar");
path.endsWith("bbf.jar");  // true
path.endsWith(".jar");     // false

Using the PathMatcher

@Test
public void visitFile2() throws IOException {
  // Find java and txt files
  String glob = "glob:**/*.{java,txt}";
  String path = "D:\\work_java\\bbf\\CORE";

  final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);

  Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
      if (pathMatcher.matches(file)) {
        System.out.println(file);
      }
      return FileVisitResult.CONTINUE;
    }
  });
}

The parameter syntax of getPathMatcher method: rule: pattern, in which rule supports glob and regex.

Global rule glob

Match the string of the path using a pattern similar to regular expressions but simpler syntax.

  • glob:*.java matches files ending in java
  • glob: *. * matching files containing '.'
  • glob:*.{java,class} matches files ending in java or class
  • glob:foo.? matches files that start with Foo and have a character extension
  • glob:/home / * / * matching on unix platform, such as / home/gus/data, etc.
  • glob:/home / * * match on unix platform, for example, / home/gus, / home/gus/data
  • glob:c: \ \ \ * match on windows platform, for example, c:foo, c:bar, note string escape

Rule description

  • *Match zero or more characters with the name component, not across directories
  • **Match zero or more characters with name components, spanning directories (including subdirectories)
  • ? character and name components that match a character
  • \Escape character, for example, \ {indicates matching left curly bracket
  • [] matches the range in the formula bracket expression, hyphen (-) specifies the range. For example, [a B C] matches "a", "B" and "C"; [a-z] matches from "a" to "z"; [abce-g] matches "a", "B", "C", "e", "f", "g";
  • [! a-c] matches any character except "a", "b", "C"
  • {} any sub pattern in the matching group. Multiple sub patterns are separated by "," and cannot be nested.

Regular rule

Use regular expressions supported by java.util.regex.Pattern.

Example

Gets the file with the specified extension

The purpose of the following test cases is to obtain the. properties and. html files under the specified directory.

/**
 * Recursive traversal, string judgment
 *
 * @throws IOException IO abnormal
 */
@Test
public void visitFile1() throws IOException {
  String path = "D:\\work_java\\hty\\HTY_CORE";

  Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
      String pathStr = file.toString();
      if (pathStr.endsWith("properties") || pathStr.endsWith("html")) {
        System.out.println(file);
      }
      return FileVisitResult.CONTINUE;
    }
  });
}

/**
 * Recursive traversal, glob mode
 *
 * @throws IOException IO abnormal
 */
@Test
public void visitFile2() throws IOException {
  String glob = "glob:**/*.{properties,html}";
  String path = "D:\\work_java\\hty\\HTY_CORE";

  final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);

  Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
      if (pathMatcher.matches(file)) {
        System.out.println(file);
      }
      return FileVisitResult.CONTINUE;
    }
  });
}

/**
 * Recursive traversal, regular pattern
 *
 * @throws IOException IO abnormal
 */
@Test
public void visitFile3() throws IOException {
  // (? i) ignore case, (?:) mark that the matching group should not be captured
  String reg = "regex:.*\\.(?i)(?:properties|html)";
  String path = "D:\\work_java\\hty\\HTY_CORE";

  final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(reg);

  Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
      if (pathMatcher.matches(file)) {
        System.out.println(file);
      }
      return FileVisitResult.CONTINUE;
    }
  });
}

Find the specified file

/**
 * Find the specified file
 *
 * @throws IOException IO abnormal
 */
@Test
public void visitFile() throws IOException {
  String path = "D:\\work_java\\hty\\HTY_CORE\\src";

  Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
      // With endsWith, it must be a segment of the path, not several characters
      if (file.endsWith("log.java")) {
        System.out.println(file);
        // Find file, terminate operation
        return FileVisitResult.TERMINATE;
      }
      return FileVisitResult.CONTINUE;
    }
  });
}

Traverse single level directory

Using DirectoryStream will get the directory and files under the specified directory. You can use the second parameter of newDirectoryStream for filtering, glob syntax.

/**
 * Traverse single level directory
 *
 * @throws IOException IO abnormal
 */
@Test
public void dir() throws IOException {
  Path source = Paths.get("D:\\work_java\\hty\\HTY_CORE\\src\\main\\resources");
  try (DirectoryStream<Path> stream = Files.newDirectoryStream(source, "*.xml")) {
    Iterator<Path> ite = stream.iterator();
    while (ite.hasNext()) {
      Path pp = ite.next();
      System.out.println(pp.getFileName());
    }
  }
}

Copy files to new directory

/**
 * Recursive replication
 *
 * @throws IOException IO abnormal
 */
@Test
public void copyAll() throws IOException {
  Path source = Paths.get("D:\\work_java\\hty\\HTY_CORE\\src");
  Path target = Paths.get("D:\\temp\\core");
  // Source folder is not a directory
  if (!Files.isDirectory(source)) {
    throw new IllegalArgumentException("Source folder error");
  }
  // Level series of source path
  int sourcePart = source.getNameCount();
  Files.walkFileTree(source, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
        throws IOException {
      // Create a subfolder corresponding to dir in the target folder
      Path subDir;
      if (dir.compareTo(source) == 0) {
        subDir = target;
      } else {
        // Get the pathname of the relative original path, and then combine it on the target
        subDir = target.resolve(dir.subpath(sourcePart, dir.getNameCount()));
      }
      Files.createDirectories(subDir);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      Files.copy(file, target.resolve(file.subpath(sourcePart, file.getNameCount())),
          StandardCopyOption.REPLACE_EXISTING);
      return FileVisitResult.CONTINUE;
    }
  });
  System.out.println("Copy completed");
}

Copying files and streams

/**
 * Stream copy to file
 *
 * @throws IOException IO abnormal
 */
@Test
public void copy1() throws IOException {
  Path source = Paths.get("D:\\work_java\\hty\\HTY_CORE\\src\\main\\resources\\ehcache.xml");
  Path target = Paths.get("D:\\temp\\");
  if (!Files.exists(target)) {
    Files.createDirectories(target);
  }
  Path targetFile = target.resolve(source.getFileName());
  try (InputStream fs = FileUtils.openInputStream(source.toFile())) {
    Files.copy(fs, targetFile, StandardCopyOption.REPLACE_EXISTING);
  }
}

/**
 * File copy to stream
 *
 * @throws IOException IO abnormal
 */
@Test
public void copy2() throws IOException {
  Path source = Paths.get("D:\\work_java\\hty\\HTY_CORE\\src\\main\\resources\\ehcache.xml");
  Path target = Paths.get("D:\\temp\\core");
  Path targetFile = target.resolve(source.getFileName());
  if (!Files.exists(target)) {
    Files.createDirectories(target);
  }
  try (OutputStream fs = FileUtils.openOutputStream(targetFile.toFile());
      OutputStream out = new BufferedOutputStream(fs)) {
    Files.copy(source, out);
  }
}

Path and File conversion

/**
 * Path Conversion to File
 */
@Test
public void testPath() {
  File file = new File("D:\\work_java\\hty\\HTY_CORE");
  System.out.println(file.toURI());
  System.out.println(file.getAbsolutePath());
  System.out.println(file.getName());

  System.out.println("-------");
  Path path = Paths.get(file.toURI());
  System.out.println(path.toUri());
  System.out.println(path.toAbsolutePath());
  System.out.println(path.getFileName());

  System.out.println("-------");
  File f = path.toFile();
  System.out.println(f.getAbsolutePath());
}

Tags: Java xml Unix Ehcache

Posted on Wed, 23 Oct 2019 02:17:53 -0700 by hhisc383