使用Java删除具有相同前缀字符串的文件

发布于 2024-12-01 23:08:37 字数 729 浏览 1 评论 0原文

我的目录中有大约 500 个文本文件,每个文件的文件名都具有相同的前缀,例如:dailyReport_

文件的后半部分是文件的日期。 (例如 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);
}

但是我可以删除具有特定前缀的文件吗? (例如第 8 个月的 dailyReport08)我可以使用 rm -rf dailyReport08*.txt 在 shell 脚本中轻松完成此操作。

但是 File f=new File("dailyReport_08*.txt"); 在 Java 中不起作用(如预期)。

现在,Java 中是否可以实现类似的操作,无需运行循环来搜索目录中的文件?

我可以使用一些类似于 shell 脚本中使用的 * 的特殊字符来实现此目的吗?

I have around 500 text files inside a directory with each with the same prefix in their filename, for example: dailyReport_.

The latter part of the file is the date of the file. (For example dailyReport_08262011.txt, dailyReport_08232011.txt)

I want to delete these files using a Java procedure. (I could go for a shell script and add it a job in the crontab but the application is meant to used by laymen).

I can delete a single file using something like this:

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

but can I delete the files having a certain prefix? (e.g. dailyReport08 for the 8th month) I could easily do that in shell script by using rm -rf dailyReport08*.txt .

But File f=new File("dailyReport_08*.txt"); doesnt work in Java (as expected).

Now is anything similar possible in Java without running a loop that searches the directory for files?

Can I achieve this using some special characters similar to * used in shell script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

梦年海沫深 2024-12-08 23:08:37

不,你不能。与 shell 脚本相比,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() );
    }
}

No, you can't. Java is rather low-level language -- comparing with shell-script -- so things like this must be done more explicetly. You should search for files with required mask with folder.listFiles(FilenameFilter), and iterate through returned array deleting each entry. Like this:

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() );
    }
}
对你再特殊 2024-12-08 23:08:37

您可以使用循环

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

You can use a loop

for (File f : directory.listFiles()) {
    if (f.getName().startsWith("dailyReport_")) {
        f.delete();
    }
}
じ违心 2024-12-08 23:08:37

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)

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)
如梦亦如幻 2024-12-08 23:08:37

对于 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 时首选路径。

With 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;
}

Simple version:

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

Modify the Path/String argument as needed. You can even convert between File and Path. Path is preferred for Java >= 8.

少女情怀诗 2024-12-08 23:08:37

像这样使用 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();
}

Use FileFilter like so:

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();
}
软糯酥胸 2024-12-08 23:08:37

我知道我参加聚会迟到了。但是,为了将来的参考,我想贡献一个不涉及循环的 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 它将深度优先遍历目录。也就是说,如果文件被埋在不同的目录中。

I know I'm late to the party. However, for future reference, I wanted to contribute a java 8 stream solution that doesn't involve a loop.

It may not be pretty. I welcome suggestions to make it look better. However, it does the job:

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

Alternatively, you can use Files.walk which will traverse the directory depth-first. That is, if the files are buried in different directories.

橪书 2024-12-08 23:08:37

There isn't a wildcard but you can implement a FilenameFilter and check the path with a startsWith("dailyReport_"). Then calling File.listFiles(filter) gives you an array of Files that you can loop through and call delete() on.

失与倦" 2024-12-08 23:08:37

我同意 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() );
    }
}

享受 !

I agree with BegemoT.

However, just one optimization:
If you need a simple FilenameFilter, there is a class in the Google packages.
So, in this case you do not even have to create your own anonymous class.

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 !

┊风居住的梦幻卍 2024-12-08 23:08:37

没有循环你就无法做到这一点。但你可以增强这个循环。首先问大家一个问题:“循环中查找和删除有什么问题吗?”如果由于某种原因它太慢,您可以在单独的线程中运行循环,这样它就不会影响您的用户界面。

其他建议 - 将您的每日报告放在一个单独的文件夹中,然后您将能够删除该文件夹及其所有内容。

You can't do it without a loop. But you can enhance this loop. First of all, ask you a question: "what's the problem with searching and removing in the loop?" If it's too slow for some reason, you can just run your loop in a separate thread, so that it will not affect your user interface.

Other advice - put your daily reports in a separate folder and then you will be able to remove this folder with all content.

深白境迁sunset 2024-12-08 23:08:37

或在斯卡拉

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

or in scala

new java.io.File(<<pathStr>>).listFiles.filter(_.getName.endsWith(".txt")).foreach(_.delete())
混吃等死 2024-12-08 23:08:37

看看Apache FileUtils,它提供了许多方便的文件操作。

Have a look at Apache FileUtils which offers many handy file manipulations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文