从nio中的模式或java

时间:2019-02-13 10:46:50

标签: java java-8

我有一个存储100万个文件的位置。我想获取列表中的所有文件,并从该列表中找到文件名中包含单词的所有文件。这里唯一重要的是性能应该非常好。所有事情都应该很快发生,因此我正在寻找最快的方法。我很困惑应该使用Java传统文件对象还是应该使用NIO。我尝试了文件对象,如下所示:

    String[] fileList = null;
    String fileNamePart = "somepartoffileName";
      try{
        File rootFolder = new File(dir);
        if(rootFolder.isDirectory()){
            fileList = rootFolder.list();

       }
        catch(Exception e){
        System.out.println("Not a valid directory "+dir);
    }

    String[] listFiles = Arrays.stream(fileList).filter(s -> 
    s.contains(FileNamePart)).toArray(String []::new);

有没有更快的方法来实现这一目标?我不介意使用文件数组或nio的东西,但我的性能应该更快。另外,要匹配的模式可以是1到1000。因此,可以有一个字符串要匹配,或者该字符串可以包含1000个逗号分隔的值

3 个答案:

答案 0 :(得分:1)

最好不要创建所有文件的列表。传统上可以使用FileNameFilter,但可以使用新的流:

Path path = Paths.get(dir);
String[] listFiles = Files.list(path)
    .map(p -> p.getFileName().toString())
    .filter(s -> s.contains(FileNamePart)).toArray(String []::new);

列表似乎更通用:

List<String> listFiles = Files.list(path)
    .map(p -> p.getFileName().toString())
    .filter(s -> s.contains(FileNamePart))
    .collect(Collectors.toList());

感谢@jaspreet提到了不需要的子目录(我用.walk而不是.list)。

答案 1 :(得分:0)

您应该利用FileVisitor中的NIO2。 Oracle在各种情况下都详细介绍了example遍历文件树的情况:

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

// The file we are looking for.
Path lookingFor = ...;

public FileVisitResult
    visitFile(Path file,
        BasicFileAttributes attr) {
    if (file.getFileName().equals(lookingFor)) {
        System.out.println("Located file: " + file);
        return TERMINATE;
    }
    return CONTINUE;
}

您不需要为此将整个列表存储在内存中。

答案 2 :(得分:0)

即使使用Java 8之前的标准,您的代码也不必要地复杂。 API specification没有提到为无效目录引发的任何异常(该方法将返回null),因此没有理由添加此异常处理。此外,如果文件不是目录,该方法将返回null,因此rootFolder.isDirectory()测试也已过时。

因此,获取未过滤的列表就像

File rootFolder = new File(dir);
String[] fileList = rootFolder.list();

,并且很容易使用Java 8功能添加过滤器,现在调用File.list(FilenameFilter)

File rootFolder = new File(dir);
String[] fileList = rootFolder.list((p, n) -> n.contains(fileNamePart));