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

Posted

技术标签:

【中文标题】使用 Java 在文件夹中查找文件【英文标题】:Find files in a folder using Java 【发布时间】:2011-06-18 15:51:56 【问题描述】:

如果搜索文件夹说C:\example我需要做什么

然后我需要检查每个文件并检查它是否与几个开始字符匹配,以便文件开始

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

因此,如果文件以 temp 开头并具有扩展名 .txt 我想将该文件名放入 File file = new File("C:/example/temp***.txt); 以便我可以读取文件,然后循环需要移动到下一个文件检查是否符合上述要求。

【问题讨论】:

【参考方案1】:

从 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()));

【讨论】:

【参考方案2】:

正如@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);
        
    

我将演示如何使用 recursivebfsdfs 来完成工作。

递归

    /**
 * 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();

【讨论】:

【参考方案3】: Matcher.find 和 Files.walk 方法可能是一种以更灵活的方式搜索文件的选项 String.format 结合正则表达式来创建搜索限制 Files.isRegularFile 检查路径是否不是目录、符号链接等。

用法:

//Searches file names (start with "temp" and extension ".txt")
//in the current directory and subdirectories recursively
Path initialPath = Paths.get(".");
PathUtils.searchRegularFilesStartsWith(initialPath, "temp", ".txt").
                                       stream().forEach(System.out::println);

来源:

public final class PathUtils 

    private static final String startsWithRegex = "(?<![_ \\-\\pL\\d\\[\\]\\(\\) ])";
    private static final String endsWithRegex = "(?=[\\.\\n])";
    private static final String containsRegex = "%s(?:[^\\/\\\\]*(?=((?i)%s(?!.))))";

    public static List<Path> searchRegularFilesStartsWith(final Path initialPath, 
                             final String fileName, final String fileExt) throws IOException 
        return searchRegularFiles(initialPath, startsWithRegex + fileName, fileExt);
    

    public static List<Path> searchRegularFilesEndsWith(final Path initialPath, 
                             final String fileName, final String fileExt) throws IOException 
        return searchRegularFiles(initialPath, fileName + endsWithRegex, fileExt);
    

    public static List<Path> searchRegularFilesAll(final Path initialPath) throws IOException 
        return searchRegularFiles(initialPath, "", "");
    

    public static List<Path> searchRegularFiles(final Path initialPath,
                             final String fileName, final String fileExt)
            throws IOException 
        final String regex = String.format(containsRegex, fileName, fileExt);
        final Pattern pattern = Pattern.compile(regex);
        try (Stream<Path> walk = Files.walk(initialPath.toRealPath())) 
            return walk.filter(path -> Files.isRegularFile(path) &&
                                       pattern.matcher(path.toString()).find())
                    .collect(Collectors.toList());
        
    

    private PathUtils() 
    

Try startsWith \txt\temp\tempZERO0.txt 的正则表达式:

(?<![_ \-\pL\d\[\]\(\) ])temp(?:[^\/\\]*(?=((?i)\.txt(?!.))))

Try endsWith \txt\temp\ZERO0temp.txt 的正则表达式:

temp(?=[\\.\\n])(?:[^\/\\]*(?=((?i)\.txt(?!.))))

Try 包含 \txt\temp\tempZERO0tempZERO0temp.txt 的正则表达式:

temp(?:[^\/\\]*(?=((?i)\.txt(?!.))))

【讨论】:

【参考方案4】:

从 Java 1.8 开始,您可以使用 Files.list 来获取流:

Path findFile(Path targetDir, String fileName) throws IOException 
    return Files.list(targetDir).filter( (p) -> 
        if (Files.isRegularFile(p)) 
            return p.getFileName().toString().equals(fileName);
         else 
            return false;
        
    ).findFirst().orElse(null);

【讨论】:

【参考方案5】:

您提供文件的名称、要搜索的目录路径,然后让它完成工作。

private static String getPath(String drl, String whereIAm) 
    File dir = new File(whereIAm); //StaticMethods.currentPath() + "\\src\\main\\resources\\" + 
    for(File e : dir.listFiles()) 
        if(e.isFile() && e.getName().equals(drl)) return e.getPath();
        if(e.isDirectory()) 
            String idiot = getPath(drl, e.getPath());
            if(idiot != null) return idiot;
        
    
    return null;

【讨论】:

【参考方案6】:

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

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

见:

org.apache.commons.io.FileUtils org.apache.commons.io.filefilter.FileFilterUtils https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/filefilter/IOFileFilter.html

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

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

【讨论】:

这是更性感的解决方案【参考方案9】:

Appache commons IO 各种

FilenameUtils.wildcardMatch

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

【讨论】:

如此简洁的答案很容易被标记为低质量。 我的声誉不允许我添加评论。我可以贡献的唯一方法是添加另一个答案。我编辑了原始帖子以添加更多详细信息。【参考方案10】:

列出给定目录中的 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;
        
    

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】:

您可以使用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");
  
);

【讨论】:

+1 因为变量名称比你之前 2 分钟发布的几乎相同的代码更令人愉悦。 @Null Set,这个答案是在我写我的时候写的,所以这不像我复制了贾斯汀写的东西并重新命名了变量...... :) 谢谢你的投票. +1 和我的想法一模一样。 @Justin 'jjnguy' Nelson 回到你身边! +1 因为你的变量被命名得更好,而且你的 endwith 有扩展点【参考方案13】:

你想要的是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");
    
);

【讨论】:

BTW Java 在 Windows 下可以很好地处理斜线 (/)。所以不需要反斜杠(并转义它)。 如果你在 Java 7 下,你可以/应该使用 java.nio.FileSystems.getDefault().getPath(String dir1, String dir2, ...) 在一个真正的“多平台方式” @beder 是java.nio.file.FileSystems

以上是关于使用 Java 在文件夹中查找文件的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse 查找

如何在 Java 中使用 SimpleFileVisitor 查找编码可能不同的文件名?

查找文件的当前大小与文件 java 标题中的数量

使用java在文本文件中查找字符串的问题

关于eclipse中java项目管理中如何查找哪个类文件包含main

java 如何在指定文件夹下查找文件