使用通配符(*)匹配的递归文件搜索

时间:2013-11-29 13:48:40

标签: java recursion wildcard

我将此代码写入搜索文件:

package filesearch;

import java.io.File;

public class FileSearch {

    public void walk(String path, String partOfFile) {
        File root = new File(path);
        File[] list = root.listFiles();

        if (list == null)
            return;

        for (File f : list) {
            if (f.isDirectory()) {
                walk(f.getAbsolutePath(), partOfFile);
            } else {
                if (f.getAbsolutePath().contains(partOfFile)) {
                    System.out.println("File:" + f.getAbsoluteFile());
                }
            }
        }
    }

    public static void main(String[] args) {
        FileSearch fw = new FileSearch();
        fw.walk("g:\\", "abs");
    }
}

我想使用通配符(*)。那么如果(*)是模式的第一个或最后一个字符,我可以通过添加以下代码来实现它:

if(f.getAbsolutePath().startsWith(partOfFile)){
    System.out.println( "File:" + f.getAbsoluteFile() );
}
if(f.getAbsolutePath().endWith(partOfFile)){
    System.out.println( "File:" + f.getAbsoluteFile() );
}

当我有多个通配符(*)和通配符(*)位于模式中间时,如何处理?

4 个答案:

答案 0 :(得分:2)

试试这个程序。

import java.io.File;

public class FileSearch
{

public void walk( String path, String partOfFile )
{
    File root = new File( path );
    File[] list = root.listFiles();
    if ( list == null )
        return;

    for ( File f : list )
    {
        if ( f.isDirectory() )
        {
            walk( f.getAbsolutePath(), partOfFile );
        }
        else
        {
            boolean isFileMatched = isFileMatched( f, partOfFile);
            if ( isFileMatched )
                System.out.println( "File:" + f.getAbsoluteFile() );
        }
    }
}

private boolean isFileMatched( File file, String partOfFile )
{
    boolean isMatched = true;
    if ( file == null || partOfFile == null )
        return false;

    String fileName = file.getName();

    //to ignore extension
    if ( fileName.contains( "." ) )
        fileName = fileName.substring( 0, fileName.lastIndexOf( "." ) );

    String[] tokens = null;
    if ( partOfFile.contains( "*" ) )
    {
        if ( partOfFile.startsWith( "*" ) && partOfFile.endsWith( "*" ) )
        {
            tokens = partOfFile.split( "\\*" );
            isMatched = isTokenMatched( isMatched, fileName, tokens );
        }
        else if ( partOfFile.startsWith( "*" ) )
        {
            String suffix = partOfFile.substring( partOfFile.lastIndexOf( "*" ) + 1 );
            if ( fileName.endsWith( suffix ) )
            {
                tokens = partOfFile.split( "\\*" );
                isMatched = isTokenMatched( isMatched, fileName, tokens );
            }
            else
                isMatched = false;
        }
        else if ( partOfFile.endsWith( "*" ) )
        {
            String prefix = partOfFile.substring( 0, partOfFile.indexOf( "*" ) );
            if ( fileName.startsWith( prefix ) )
            {
                tokens = partOfFile.split( "\\*" );
                isMatched = isTokenMatched( isMatched, fileName, tokens );
            }
            else
                isMatched = false;
        }
        else
        {
            if ( !fileName.equals( partOfFile ) )
                isMatched = false;
        }
    }
    return isMatched;
}

private boolean isTokenMatched( boolean isMatched, String fileName, String[] tokens )
{
    if ( tokens != null )
    {
        for ( String token : tokens )
        {
            if ( !fileName.contains( token ) )
            {
                isMatched = false;
                break;
            }
        }
    }
    return isMatched;
}

public static void main( String[] args )
{
    FileSearch fw = new FileSearch();
   fw.walk("g:\\" , "abs");
}
}

答案 1 :(得分:1)

还有很多其他方法可以获得你想要的东西,但是使用通配符将模式转换为正则表达式在编码和可读性方面是最有效的。只需使用startsWith和endWith,你就可以使用匹配函数和一个正则表达式,以快速验证你想要的。

您所要做的就是用*替换模式中的.*?。这样,带有通配符的模式将转换为非贪婪的正则表达式。然后,只需使用函数来验证字符串中是否存在模式。下面的示例验证中间是否有*。这种方法适用于任意数量的通配符。

partOfFile = ".*?"+partOfFile.replace("*",".*?")+".*?";  // fi*e.log becomes .*?fi.*e.log.*?
if(f.getAbsolutePath().matches(partOfFile))
{
    System.out.println( "File:" + f.getAbsoluteFile() );
}

匹配函数将正则表达式作为输入。我们正在放置。*?在模式之前和之后确保我们可以在模式之前和之后有一些字符。

答案 2 :(得分:-1)

使用regular expressions过滤文件名。

答案 3 :(得分:-1)

使用Files.newDirectoryStream(Path,String glob)

更多信息:http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#newDirectoryStream(java.nio.file.Path,java.lang.String)