从nio模式或java文件对象中查找文件名的最快方法

从nio模式或java文件对象中查找文件名的最快方法,java,java-8,Java,Java 8,我有一个存储了一百万个文件的位置。我想获取列表中的所有文件,并从该列表中查找文件名中包含单词的所有文件。这里唯一重要的是性能应该非常好。所有的事情都应该发生得很快,因此我正在寻找最快的方法。我不知道是应该使用java传统文件对象还是应该使用NIO。我已按如下方式尝试了文件对象: String[] fileList = null; String fileNamePart = "somepartoffileName"; try{ File rootFold

我有一个存储了一百万个文件的位置。我想获取列表中的所有文件,并从该列表中查找文件名中包含单词的所有文件。这里唯一重要的是性能应该非常好。所有的事情都应该发生得很快,因此我正在寻找最快的方法。我不知道是应该使用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个逗号分隔的值

最好不要创建所有文件的列表。传统上,可以使用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。

你应该从中获益。Oracle详细介绍了在各种情况下遍历文件树的方法:

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

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

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

因此,获取未经筛选的列表非常简单

File rootFolder = new File(dir);
String[] fileList = rootFolder.list();
使用Java 8的功能,很容易添加一个过滤器(现在正在调用):

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

您应该阅读您使用的API的源代码,以便更好地了解它们的功能。File.list将百万字符串加载到内部ArrayList中。将所有条目从它复制到另一个百万条目的字符串数组。然后,您将过滤该项并将匹配项复制到第三个数组中。我不知道你怎么能找到一个性能更差的API。我认为应该是Files.list方法,而不是walk方法,因为他不想在目录中也找到文件。