180

これは本当に簡単なはずです。次のような文字列がある場合:

../Test?/sample*.txt

では、このパターンに一致するファイルのリストを取得する一般的に受け入れられている方法は何ですか? (例: and と一致する必要がありますが、 orとは一致../Test1/sample22b.txt../Test4/sample-spiffy.txtません)../Test3/sample2.blah../Test44/sample2.txt

私は見てみましたがorg.apache.commons.io.filefilter.WildcardFileFilter、それは正しい獣のようですが、相対ディレクトリパスでファイルを見つけるためにそれを使用する方法がわかりません.

ワイルドカード構文を使用しているため、ant のソースを探すことができると思いますが、ここには明らかな何かが欠けているに違いありません。

編集:上記の例は単なるサンプルケースです。実行時にワイルドカードを含む一般的なパスを解析する方法を探しています。mmyersの提案に基づいてその方法を見つけましたが、ちょっと面倒です。言うまでもありませんJava JREは、単一の引数からメイン(String []引数)の単純なワイルドカードを自動解析して、時間と手間を「節約」するようです...ミックス。)

4

17 に答える 17

88

Apache Ant の DirectoryScanner を検討してください。

DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"**/*.java"});
scanner.setBasedir("C:/Temp");
scanner.setCaseSensitive(false);
scanner.scan();
String[] files = scanner.getIncludedFiles();

ant.jar を参照する必要があります (ant 1.7.1 の場合は ~ 1.3 MB)。

于 2009-04-30T05:55:10.673 に答える
32

Files#findJava 8以降、から直接メソッドを使用できますjava.nio.file

public static Stream<Path> find(Path start,
                                int maxDepth,
                                BiPredicate<Path, BasicFileAttributes> matcher,
                                FileVisitOption... options)

使用例

Files.find(startingPath,
           Integer.MAX_VALUE,
           (path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);
于 2016-06-29T14:23:35.600 に答える
18

今のところ役に立たないかもしれませんが、JDK 7は、「その他のNIO機能」の一部としてglobとregexのファイル名を一致させることを目的としています。

于 2009-04-27T17:25:57.060 に答える
13

ワイルドカード ライブラリは、グロブと正規表現の両方のファイル名の一致を効率的に行います。

http://code.google.com/p/wildcard/

実装は簡潔です。JAR はわずか 12.9 キロバイトです。

于 2010-12-16T01:42:08.557 に答える
12

外部インポートを使用しない簡単な方法は、このメソッドを使用することです

billing_201208.csv 、billing_201209.csv 、billing_201210.csv という名前の csv ファイルを作成しましたが、正常に動作しているようです。

上記のファイルが存在する場合、出力は次のようになります

found billing_201208.csv
found billing_201209.csv
found billing_201210.csv

    //Import を使用 ->import java.io.File
        public static void main(String[] args) {
        文字列 pathToScan = ".";
        文字列 target_file ; // fileThatYouWantToFilter
        File folderToScan = new File(pathToScan);

    File[] listOfFiles = folderToScan.listFiles();

     for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                target_file = listOfFiles[i].getName();
                if (target_file.startsWith("billing")
                     && target_file.endsWith(".csv")) {
                //You can add these files to fileList by using "list.add" here
                     System.out.println("found" + " " + target_file); 
                }
           }
     }    
}

于 2012-11-05T07:45:56.650 に答える
6

別の回答に投稿されているように、ワイルドカード ライブラリはグロブと正規表現の両方のファイル名の一致に対して機能します: http://code.google.com/p/wildcard/

次のコードを使用して、*nix スタイルのファイル システムで絶対および相対を含む glob パターンを照合しました。

String filePattern = String baseDir = "./";
// If absolute path. TODO handle windows absolute path?
if (filePattern.charAt(0) == File.separatorChar) {
    baseDir = File.separator;
    filePattern = filePattern.substring(1);
}
Paths paths = new Paths(baseDir, filePattern);
List files = paths.getFiles();

私はこれを行うために Apache commons io ライブラリ (Vladimir の回答を参照) で FileUtils.listFiles メソッドを取得しようと時間を費やしましたが、成功しませんでした (私は今気づいています/一度に 1 つのディレクトリまたはファイルに一致するパターンしか処理できないと思います)。 .

さらに、ファイル システム全体を検索せずに任意のユーザー指定の絶対型 glob パターンを処理するために正規表現フィルター (Fabian の回答を参照) を使用すると、最大の非正規表現/グロブ プレフィックスを決定するために、指定されたグロブの前処理が必要になります。

もちろん、Java 7 は要求された機能を適切に処理するかもしれませんが、残念ながら私は今のところ Java 6 で立ち往生しています。ライブラリのサイズは 13.5kb と比較的小さいです。

レビュー担当者への注意: このライブラリに言及している既存の回答に上記を追加しようとしましたが、編集は拒否されました。これをコメントとして追加するのに十分な担当者もいません。何か良い方法はないでしょうか...

于 2013-02-01T00:11:53.093 に答える
5

Java7 のグロブ:ファイルの検索. (サンプル)

于 2013-06-03T13:02:33.060 に答える
5

を使用できるはずですWildcardFileFilterSystem.getProperty("user.dir")作業ディレクトリを取得するために使用するだけです。これを試して:

public static void main(String[] args) {
File[] files = (new File(System.getProperty("user.dir"))).listFiles(new WildcardFileFilter(args));
//...
}

ワイルドカード フィルターが を使用すると仮定*すると、に置き換える必要はありません。私はこれをテストしていませんが、パターンとファイル フィルターを常に使用しています。[.*]java.regex.Pattern

于 2011-07-07T23:55:52.527 に答える
3

Apache フィルタは、既知のディレクトリ内のファイルを反復処理するために構築されています。ディレクトリでもワイルドカードを使用できるようにするには、「\」または「/」でパスを分割し、各部分で個別にフィルタを実行する必要があります。

于 2009-04-27T17:02:49.923 に答える
0

JDK FileVisitor インターフェイスを実装します。ここに例があります http://wilddiary.com/list-files-matching-a-naming-pattern-java/

于 2014-12-16T15:36:40.490 に答える
0

利用方法:

public static boolean isFileMatchTargetFilePattern(final File f, final String targetPattern) {
        String regex = targetPattern.replace(".", "\\.");  //escape the dot first
        regex = regex.replace("?", ".?").replace("*", ".*");
        return f.getName().matches(regex);

    }

jUnit テスト:

@Test
public void testIsFileMatchTargetFilePattern()  {
    String dir = "D:\\repository\\org\my\\modules\\mobile\\mobile-web\\b1605.0.1";
    String[] regexPatterns = new String[] {"_*.repositories", "*.pom", "*-b1605.0.1*","*-b1605.0.1", "mobile*"};
    File fDir = new File(dir);
    File[] files = fDir.listFiles();

    for (String regexPattern : regexPatterns) {
        System.out.println("match pattern [" + regexPattern + "]:");
        for (File file : files) {
            System.out.println("\t" + file.getName() + " matches:" + FileUtils.isFileMatchTargetFilePattern(file, regexPattern));
        }
    }
}

出力:

match pattern [_*.repositories]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:true
match pattern [*.pom]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [*-b1605.0.1*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
match pattern [*-b1605.0.1]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [mobile*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
于 2016-01-23T19:37:40.483 に答える
0

次のようなことをしないのはなぜですか:

File myRelativeDir = new File("../../foo");
String fullPath = myRelativeDir.getCanonicalPath();
Sting wildCard = fullPath + File.separator + "*.txt";

// now you have a fully qualified path

そうすれば、相対パスを気にする必要がなくなり、必要に応じてワイルドカードを使用できます。

于 2009-04-27T17:07:07.150 に答える