2011-08-30 3 views
21

ファイル名に同じ接頭辞を持つディレクトリ内に約500のテキストファイルがあります。dailyReport_です。Javaを使用して同じプレフィックス文字列を含むファイルを削除する

ファイルの後半はファイルの日付です。 (たとえば、dailyReport_08262011.txt,dailyReport_08232011.txt

Javaプロシージャを使用してこれらのファイルを削除したいとします(シェルスクリプトを使用してcrontabにジョブを追加することもできますが、アプリケーションはlaymenによって使用されます)。

私はこの

 try{ 
      File f=new File("dailyReport_08232011.txt"); 
      f.delete(); 
     } 
     catch(Exception e){ 
       System.out.println(e); 
     } 

のようなものを使用して1つのファイルを削除することができますが、私は特定の接頭辞持つファイルを削除することができます。私は簡単に使用してシェルスクリプトでそれを行うことができます(たとえば、8月のdailyReport08を) rm -rf dailyReport08*.txt

しかし、File f=new File("dailyReport_08*.txt");は期待通りにJavaで動作しません。

Java では、ディレクトリを検索するループを実行することなく、このようなことが可能です。

シェルスクリプトで使用されている*に似た特殊文字を使用してこれを達成できますか?

+3

ループの何が問題? – user802421

+0

私も同じ感じです...なぜループしないのですか? – amod

+0

私は可能なループを知っています...しかし、私が言ったように、ファイル数が多すぎるかもしれません(500は単なる数字です)...そうではなくループを使用する代わりに、シェルスクリプトのように私はそれがより良いと感じています... –

答えて

30

を使用することができます。 Javaは、シェルスクリプトと比較してむしろ低レベルの言語なので、このようなことはもっと明快に行う必要があります。 folder.listFiles(FilenameFilter)で必要なマスクを持つファイルを検索し、返された配列を繰り返して各エントリを削除する必要があります。このように:

final File folder = ... 
final File[] files = folder.listFiles(new FilenameFilter() { 
    @Override 
    public boolean accept(final File dir, 
          final String name) { 
     return name.matches("dailyReport_08.*\\.txt"); 
    } 
}); 
for (final File file : files) { 
    if (!file.delete()) { 
     System.err.println("Can't remove " + file.getAbsolutePath()); 
    } 
} 
+0

'FilenameFilter'でループを実行するよりも高速な結果を得ました...ありがとうございました –

+0

Thumb up! forループはまったくありません。 – user802421

+0

@ user802421:forループがありますが、私はパターンでファイルを検索するためのループを避けようとしていました...そして、私はこれがロジックに高速な結果を与えると私はループを使ってファイルを検索し、 .... –

3

ワイルドカードはありませんが、FilenameFilterを実装し、パスをstartsWith("dailyReport_")で確認できます。その後、File.listFiles(filter)を呼び出すと、ループしてdelete()を呼び出すことができるファイルの配列が得られます。

23

あなたはありません、することはできませんループ

for (File f : directory.listFiles()) { 
    if (f.getName().startsWith("dailyReport_")) { 
     f.delete(); 
    } 
} 
0

ループなしでは実行できません。しかし、このループを強化することができます。まず最初に、「ループ内での検索と削除の問題は何ですか?」何らかの理由で遅すぎる場合は、ループを別のスレッドで実行するだけで、ユーザーインターフェイスには影響しません。

その他のアドバイス - 毎日のレポートを別のフォルダに入れてから、すべてのコンテンツを含むこのフォルダを削除することができます。そのような

+0

毎月フォルダーが合意!!! !!! ....毎月のフォルダーに行くことができましたが、ファイルをマージするような特定の要件(いろいろな月)が面倒になる可能性があります....そして、ファイル... –

2

使用FileFilter

File dir = new File(<path to dir>); 
File[] toBeDeleted = dir.listFiles(new FileFilter() { 
    boolean accept(File pathname) { 
    return (pathname.getName().startsWith("dailyReport_08") && pathname.getName().endsWith(".txt")); 
    } 

for (File f : toBeDeleted) { 
    f.delete(); 
} 
+0

このコードは、** dailyReport_08で始まるもの(非 'txt'ファイルを含む)を削除します**また、拡張子もチェックするでしょう...しかしBegemoTが与えられたコードは完璧な結果を返します。任意の方法 –

0

は、多くの便利なファイル操作を提供していますApache FileUtilsを見てください。

0

私はBegemoTに同意します。

ただし、1つの最適化: 単純なFilenameFilterが必要な場合は、Googleパッケージにクラスがあります。 この場合、独自の匿名クラスを作成する必要はありません。

import com.google.common.io.PatternFilenameFilter; 

final File folder = ... 
final File[] files = folder.listFiles(new PatternFilenameFilter("dailyReport_08.*\\.txt")); 

// loop through the files 
for (final File file : files) { 
    if (!file.delete()) { 
     System.err.println("Can't remove " + file.getAbsolutePath()); 
    } 
} 

お楽しみください! Javaの8で

5

public static boolean deleteFilesForPathByPrefix(final String path, final String prefix) { 
    boolean success = true; 
    try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(Paths.get(path), prefix + "*")) { 
     for (final Path newDirectoryStreamItem : newDirectoryStream) { 
      Files.delete(newDirectoryStreamItem); 
     } 
    } catch (final Exception e) { 
     success = false; 
     e.printStackTrace(); 
    } 
    return success; 
} 

シンプルバージョン:必要に応じて

public static void deleteFilesForPathByPrefix(final Path path, final String prefix) { 
    try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(path, prefix + "*")) { 
     for (final Path newDirectoryStreamItem : newDirectoryStream) { 
      Files.delete(newDirectoryStreamItem); 
     } 
    } catch (final Exception e) { // empty 
    } 
} 

はパス/ String型の引数を変更します。ファイルとパスの間で変換することもできます。 Java> = 8の方がパスが優先されます。

+0

これはJava 7の時点で実際にすべて利用可能です。 – wrestang

2

私はパーティーに遅刻していることは知っています。しかし、今後の参考として、私はループを伴わないjava 8 stramソ​​リューションを提供したいと考えていました。

かわいいかもしれません。私はそれをより良く見せるための提案を歓迎します。しかし、それは仕事をしていません:

Files.list(deleteDirectory).filter(p -> p.toString().contains("dailyReport_08")).forEach((p) -> { 
    try { 
     Files.deleteIfExists(p); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}); 

また、あなたは深さ優先ディレクトリを横断しますFiles.walkを使用することができます。つまり、ファイルが別のディレクトリに埋め込まれている場合です。

+1

私はこの解決策がループを回避するとは思わない、新しい構文を使用するだけです。 –

0
new java.io.File(<<pathStr>>).listFiles.filter(_.getName.endsWith(".txt")).foreach(_.delete()) 
0

のJava 8:

final File downloadDirectory = new File("directoryPath"); 
    final File[] files = downloadDirectory.listFiles((dir,name) -> name.matches("dailyReport_.*?")); 
    Arrays.asList(files).stream().forEach(File::delete) 
関連する問題