使用Java在文件夹中查找文件

60

如果要搜索一个名为 C:\example 的文件夹,我需要做什么?

然后我需要遍历每个文件并检查是否与一些起始字符匹配,例如如果文件以以下字符开头:

temp****.txt
tempONE.txt
tempTWO.txt

所以,如果文件以temp开头且扩展名为.txt,我希望将该文件名放入 File file = new File("C:/example/temp***.txt); 中,以便我可以读取该文件,然后循环需要继续移动到下一个文件以检查它是否符合上述条件。

13个回答

80

你需要的是File.listFiles(FileNameFilter filter)方法。

它会返回符合特定过滤器条件的目标目录中的文件列表。

代码类似于:

// your directory
File f = new File("C:\\example");
File[] matchingFiles = f.listFiles(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.startsWith("temp") && name.endsWith("txt");
    }
});

3
顺带一提,在Windows下,Java可以很好地处理斜杠(/),因此不需要使用反斜杠(并对其进行转义)。 - Steve Kuo
2
如果您使用的是Java 7以下版本,您可以/应该使用java.nio.FileSystems.getDefault().getPath(String dir1, String dir2, ...)以真正的“多平台方式”连接目录/文件。 - beder
@beder 这是java.nio.file.FileSystems - TheRealChx101

37

您可以使用一个FilenameFilter,像这样:

File dir = new File(directory);

File[] matches = dir.listFiles(new FilenameFilter()
{
  public boolean accept(File dir, String name)
  {
     return name.startsWith("temp") && name.endsWith(".txt");
  }
});

2
如果你的变量名比刚刚发布的代码稍微好看一些,那么你就可以得到一个加分。 - Null Set
1
@Null Set,那个答案是我写的时候他也在写,所以不是我抄袭了Justin写的然后改了变量名... :) 谢谢你的点赞。 - Mia Clarke
+1,因为你的想法和我一模一样。 - jjnguy
@Justin 'jjnguy' Nelson 回报给你! - Mia Clarke
1
+1 是因为你的变量命名更好,并且你的 endwith 带了一个点的扩展名。 - Martin Thurau

31

我知道这是一个老问题。但只是为了完整起见,这里是 lambda 版本。

File dir = new File(directory);
File[] files = dir.listFiles((dir1, name) -> name.startsWith("temp") && name.endsWith(".txt"));

3
这是更加性感的解决方案。 - alexandre-rousseau
只获取了第一个文件,文件数组的大小为1。 - prakash krishnan

5

如@Clarke所说,您可以使用java.io.FilenameFilter按特定条件过滤文件。

作为补充,我想展示如何使用java.io.FilenameFilter在当前目录及其子目录中搜索文件。

使用常见方法getTargetFiles和printFiles来搜索文件并打印它们。

public class SearchFiles {

    //It's used in dfs
    private Map<String, Boolean> map = new HashMap<String, Boolean>();

    private File root;

    public SearchFiles(File root){
        this.root = root;
    }

    /**
     * List eligible files on current path
     * @param directory
     *      The directory to be searched
     * @return
     *      Eligible files
     */
    private String[] getTargetFiles(File directory){
        if(directory == null){
            return null;
        }

        String[] files = directory.list(new FilenameFilter(){

            @Override
            public boolean accept(File dir, String name) {
                // TODO Auto-generated method stub
                return name.startsWith("Temp") && name.endsWith(".txt");
            }

        });

        return files;
    }

    /**
     * Print all eligible files
     */
    private void printFiles(String[] targets){
        for(String target: targets){
            System.out.println(target);
        }
    }
}

我将演示如何使用递归bfsdfs来完成任务。

递归:

    /**
 * How many files in the parent directory and its subdirectory <br>
 * depends on how many files in each subdirectory and their subdirectory
 */
private void recursive(File path){

    printFiles(getTargetFiles(path));
    for(File file: path.listFiles()){
        if(file.isDirectory()){
            recursive(file);
        }
    }
    if(path.isDirectory()){
        printFiles(getTargetFiles(path));
    }
}

public static void main(String args[]){
    SearchFiles searcher = new SearchFiles(new File("C:\\example"));
    searcher.recursive(searcher.root);
}

广度优先搜索:

/**
 * Search the node's neighbors firstly before moving to the next level neighbors
 */
private void bfs(){
    if(root == null){
        return;
    }

    Queue<File> queue = new LinkedList<File>();
    queue.add(root);

    while(!queue.isEmpty()){
        File node = queue.remove();
        printFiles(getTargetFiles(node));
        File[] childs = node.listFiles(new FileFilter(){

            @Override
            public boolean accept(File pathname) {
                // TODO Auto-generated method stub
                if(pathname.isDirectory())
                    return true;

                return false;
            }

        });

        if(childs != null){
            for(File child: childs){
                queue.add(child);
            }
        }
    }
}

public static void main(String args[]){
    SearchFiles searcher = new SearchFiles(new File("C:\\example"));
    searcher.bfs();
}

深度优先搜索:

 /**
 * Search as far as possible along each branch before backtracking
 */
private void dfs(){

    if(root == null){
        return;
    }

    Stack<File> stack = new Stack<File>();
    stack.push(root);
    map.put(root.getAbsolutePath(), true);
    while(!stack.isEmpty()){
        File node = stack.peek();
        File child = getUnvisitedChild(node);

        if(child != null){
            stack.push(child);
            printFiles(getTargetFiles(child));
            map.put(child.getAbsolutePath(), true);
        }else{
            stack.pop();
        }

    }
}

/**
 * Get unvisited node of the node
 * 
 */
private File getUnvisitedChild(File node){

    File[] childs = node.listFiles(new FileFilter(){

        @Override
        public boolean accept(File pathname) {
            // TODO Auto-generated method stub
            if(pathname.isDirectory())
                return true;

            return false;
        }

    });

    if(childs == null){
        return null;
    }

    for(File child: childs){

        if(map.containsKey(child.getAbsolutePath()) == false){
            map.put(child.getAbsolutePath(), false);
        }

        if(map.get(child.getAbsolutePath()) == false){
            return child; 
        }
    }

    return null;
}

public static void main(String args[]){
    SearchFiles searcher = new SearchFiles(new File("C:\\example"));
    searcher.dfs();
}

5

看一下 java.io.File.list()FilenameFilter


4

列出给定目录中的Json文件。

import java.io.File;
    import java.io.FilenameFilter;

    public class ListOutFilesInDir {
        public static void main(String[] args) throws Exception {

            File[] fileList = getFileList("directory path");

            for(File file : fileList) {
                System.out.println(file.getName());
            }
        }

        private static File[] getFileList(String dirPath) {
            File dir = new File(dirPath);   

            File[] fileList = dir.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith(".json");
                }
            });
            return fileList;
        }
    }

4
考虑使用Apache Commons IO,它有一个名为 FileUtils 的类,其中包含一个 listFiles 方法,在您的情况下可能非常有用。

4

Appache commons IO 各种

FilenameUtils.wildcardMatch

请参阅Apache javadoc 此处。它将通配符与文件名进行匹配。因此,您可以使用此方法进行比较。


简洁的回答很容易被标记为低质量。 - joaquin
我的声誉不允许我添加评论。我唯一能做出贡献的方式是添加另一个答案。我编辑了原始帖子以添加更多细节。 - eugene

4

从Java 8开始,您可以使用Files.find方法。

Path dir = Paths.get("path/to/search");
String prefix = "prefix";

Files.find(dir, 3, (path, attributes) -> path.getFileName().toString().startsWith(prefix))
                .forEach(path -> log.info("Path = " + path.toString()));

有没有办法通过路径跳过特定文件夹,以便不进入它们? - undefined

2

为了详细说明这个回答,Apache IO Utils可能会节省您一些时间。考虑以下示例,它将递归搜索给定名称的文件:

    File file = FileUtils.listFiles(new File("the/desired/root/path"), 
                new NameFileFilter("filename.ext"), 
                FileFilterUtils.trueFileFilter()
            ).iterator().next();

See:


有没有办法以流的方式查看文件,并通过路径跳过特定文件夹,以便不进入它们? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接