首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >全球理解

全球理解
EN

Stack Overflow用户
提问于 2016-09-03 05:26:23
回答 2查看 1.4K关注 0票数 3

我需要使用以下选项/参数在java中开发一个文件扫描器:

  1. 一个目录
  2. 一个或多个模式,如*.xml、*.txt、*test.csv
  3. 递归扫描开关

我认为最好的办法是这样做:

代码语言:javascript
复制
public class FileScanningTest {

    public static void main(String[] args) throws IOException {

        String directory = "C:\\tmp\\scanning\\";
        String glob      = "**/*.xml";
        Boolean rekursiv = false;

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

        Files.walkFileTree(Paths.get(directory), new SimpleFileVisitor<Path>() {

            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                if (pathMatcher.matches(path)) {
                    System.out.println(path);
                } 
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                return FileVisitResult.CONTINUE;
            }
        });

    }

}

我不明白为什么我要把"**/“放在我的实际模式前面。此外,这也使扫描递归。如果我删除**/,应用程序将不再找到任何内容。

https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob告诉我们,**意味着递归,但是如果我删除它,为什么不能工作呢?

谁能给我个提示吗?

谢谢大家,周末愉快

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-03 05:59:42

要使用从目录*.xml开始的glob递归查找/tmp/scanning/,请看下面的示例。它与一起工作,可以做您想做的事情。它的工作方式类似于Unix实用程序。我没有在Ubuntu之外的其他操作系统上测试它,但是您只需要更改文件名分隔符。

代码语言:javascript
复制
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;

import static java.nio.file.FileVisitResult.*;
import static java.nio.file.FileVisitOption.*;

import java.util.*;


public class FileScanningTest {

    public static class Finder
            extends SimpleFileVisitor<Path> {

        private final PathMatcher matcher;
        private int numMatches = 0;

        Finder(String pattern) {
            matcher = FileSystems.getDefault()
                    .getPathMatcher("glob:" + pattern);
        }

        // Compares the glob pattern against
        // the file or directory name.
        void find(Path file) {
            Path name = file.getFileName();
            if (name != null && matcher.matches(name)) {
                numMatches++;
                System.out.println(file);
            }
        }

        // Prints the total number of
        // matches to standard out.
        void done() {
            System.out.println("Matched: "
                    + numMatches);
        }

        // Invoke the pattern matching
        // method on each file.
        @Override
        public FileVisitResult visitFile(Path file,
                                         BasicFileAttributes attrs) {
            find(file);
            return CONTINUE;
        }

        // Invoke the pattern matching
        // method on each directory.
        @Override
        public FileVisitResult preVisitDirectory(Path dir,
                                                 BasicFileAttributes attrs) {
            find(dir);
            return CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file,
                                               IOException exc) {
            System.err.println(exc);
            return CONTINUE;
        }
    }


    public static void main(String[] args)
            throws IOException {
        boolean recursive = false;
        Path startingDir = Paths.get("/tmp/scanning");
        String pattern = "*.{html,xml}";

        Finder finder = new Finder(pattern);
        if (!recursive) {
            Path dir = startingDir;
            List<File> files = new ArrayList<>();
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{xml,html}")) {
                for (Path entry : stream) {
                    files.add(entry.toFile());
                }

                for (File xmlfile : files) {
                    System.out.println(xmlfile);
                }
            } catch (IOException x) {
                throw new RuntimeException(String.format("error reading folder %s: %s",
                        dir,
                        x.getMessage()),
                        x);
            }
        } else {    
            Files.walkFileTree(startingDir, finder);
            finder.done();
        }

    }
}

测试

代码语言:javascript
复制
 ~> java FileScanningTest
/tmp/scanning/dir2/test2.xml
/tmp/scanning/blah.xml
Matched: 2

如果要匹配*.xmltest3.html,则可以使用以下模式:String pattern = "{*.xml,test3.html}";

票数 4
EN

Stack Overflow用户

发布于 2016-09-03 05:56:19

***的区别在于,*永远不会匹配目录分隔符(取决于您的操作系统) (/\ ),但是**会匹配。给定这样的文件树:

代码语言:javascript
复制
a/
  b.xml
c/
  a.xml
da.xml

模式*a.xml将只匹配da.xml (不匹配c/a.xml,因为其中包含/),而模式**a.xml将匹配da.xmlc/a.xml,模式a**.xml将只匹配a/b.xml

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39303549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档