ファイル名に同じ接頭辞を持つ_dailyReport_
_というディレクトリ内に約500個のテキストファイルがあります。
ファイルの後半は、ファイルの日付です。 (たとえば、_dailyReport_08262011.txt
_、_dailyReport_08232011.txt
_)
Javaプロシージャを使用してこれらのファイルを削除します(シェルスクリプトに移動してcrontabにジョブを追加できますが、このアプリケーションは素人向けです)。
このようなものを使用して、単一のファイルを削除できます
_ try{
File f=new File("dailyReport_08232011.txt");
f.delete();
}
catch(Exception e){
System.out.println(e);
}
_
しかし、特定のプレフィックス(たとえば、8か月目の_dailyReport08
_)を持つファイルを削除できますか?_rm -rf dailyReport08*.txt
_を使用すると、シェルスクリプトで簡単に削除できます。
しかし、File f=new File("dailyReport_08*.txt");
はJava(予想どおり)では機能しません。
これで、Java ループを実行せずにでディレクトリを検索してファイルを検索できますか?
シェルスクリプトで使用される_*
_に類似したいくつかの特殊文字を使用してこれを達成できますか?
いいえ、できません。 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() );
}
}
ループを使用できます
for (File f : directory.listFiles()) {
if (f.getName().startsWith("dailyReport_")) {
f.delete();
}
}
Java 8:
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
}
}
必要に応じてPath/String引数を変更します。ファイルとパスの間で変換することもできます。 Java> = 8。
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();
}
私はパーティーに遅れていることを知っています。ただし、今後の参考のために、ループを含まないJava 8ストリームソリューションを提供したいと考えました。
きれいではないかもしれません。見栄えを良くする提案を歓迎します。しかし、それは仕事をします:
Files.list(deleteDirectory).filter(p -> p.toString().contains("dailyReport_08")).forEach((p) -> {
try {
Files.deleteIfExists(p);
} catch (Exception e) {
e.printStackTrace();
}
});
あるいは、Files.walkを使用して、ディレクトリを最初にトラバースします。つまり、ファイルが異なるディレクトリに埋まっている場合です。
ワイルドカードはありませんが、 FilenameFilter を実装し、startsWith("dailyReport_")
でパスを確認できます。次にFile.listFiles(filter)
を呼び出すと、ループ処理してdelete()を呼び出すことができるファイルの配列が得られます。
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)
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() );
}
}
楽しい !
ループなしではできません。しかし、このループを強化できます。まず、質問をしてください:「ループ内での検索と削除の問題は何ですか?」何らかの理由で遅すぎる場合は、ループを別のスレッドで実行するだけで、ユーザーインターフェイスに影響を与えません。
その他のアドバイス-毎日のレポートを別のフォルダーに入れると、すべてのコンテンツでこのフォルダーを削除できるようになります。
Apache FileUtils をご覧ください。多くの便利なファイル操作が可能です。
new Java.io.File(<<pathStr>>).listFiles.filter(_.getName.endsWith(".txt")).foreach(_.delete())