2011-08-30 50 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)