2011-08-30 51 views
21

我在一個目錄內有大約500個文本文件,它們的文件名中有相同的前綴,它們表示爲dailyReport_使用Java刪除具有相同前綴字符串的文件

該文件的後半部分是該文件的日期。 (對於如:dailyReport_08262011.txtdailyReport_08232011.txt

我想刪除使用Java程序將這些文件(我可以去一個shell腳本,並將其添加一個工作在crontab但應用程序是指由外行使用)。

我可以使用這樣的事情

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

刪除一個單一的文件,但我可以刪除具有一定前綴的文件(例如:dailyReport08爲8個月),我可以很容易地做到這一點在shell腳本利用rm -rf dailyReport08*.txt

File f=new File("dailyReport_08*.txt");在Java中不起作用(如預期的那樣)。

現在是什麼東西可以在Java 這樣沒有運行循環搜索目錄中的文件?

我可以用一些類似於shell腳本中使用的*的特殊字符來實現嗎?

+3

有什麼不好循環? – user802421

+0

我也感覺一樣...爲什麼不循環? – amod

+0

我知道它可能與循環...但正如我所說我可能有大量的文件(500只是一個數字)...所以而不是使用循環,如果可能的其他方式如shell腳本我覺得那會更好...... –

回答

30

不,你不能。 Java是相當低級的語言 - 與shell腳本比較 - 所以像這樣的事情必須更明確地做。您應該使用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

我同意BegemoT。

但是,只有一個優化: 如果您需要一個簡單的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()); 
    } 
} 

Enjoy!

5

與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 
    } 
} 

根據需要修改路徑/字符串參數。你甚至可以在文件和路徑之間進行轉換。 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)