【问题标题】:how can I leave only last 10 newest files in a dir using java?如何使用 java 在目录中仅保留最后 10 个最新文件?
【发布时间】:2015-02-19 10:46:13
【问题描述】:

我想用一个方法来编写代码,得到一个file path 和一个file name prefix

并删除该dir path 和该file name prefix 中的所有文件,但最新的10 个文件除外。

我想使用 lambda (java 8)

但我不确定 ti 如何过滤 10 个最新文件:

   public Optional<File> getLatestFileFromDir(String baseLineFileName) {
        File baseLineFile = new File(baseLineFileName);
        File dir = baseLineFile.getParentFile();
        File[] files = dir.listFiles();

        if (files == null || files.length == 0) {
            return null;
        }
        return Arrays.asList(dir.listFiles()).stream()
                .filter(file -> isNameLikeBaseLine(file, baseLineFile.getName()))
                .max(new Comparator<File>() {
                    @Override
                    public int compare(File o1, File o2) {
                        int answer;
                        if (o1.lastModified() == o2.lastModified()) {
                            answer = 0;
                        } else if (o1.lastModified() > o2.lastModified()) {
                            answer = 1;
                        } else {
                            answer = -1;
                        }
                        return answer;
                    }
                });
    }

【问题讨论】:

    标签: java file filter lambda


    【解决方案1】:

    请找到一个完整的工作示例

    • 创建具有不同上次修改时间戳的第三个虚拟文件
    • 创建这些文件的列表
    • 随机播放它们以显示比较器按预期工作
    • 删除或显示文件,但具有最近最后修改时间戳的十个文件除外

    .

    public class KeepTopTenFiles {
    
        public static void main(String[] args) throws IOException {
            ArrayList<File> files = new ArrayList<>();
            createDummyFiles(files);
            Collections.shuffle(files);
    
            files.stream()
                    .filter((File p) -> p.getName().matches("foobar_.*"))
                    .sorted(getReverseLastModifiedComparator())
                    .skip(10)
                    // to delete the file but keep the most recent ten
                    // .forEach(x -> ((File) x).delete());
                    // or display the filenames which would be deleted
                    .forEach((x) -> System.out.printf("would be deleted: %s%n", x));
        }
    
        private static Comparator<File> getReverseLastModifiedComparator() {
            return (File o1, File o2) -> {
                if (o1.lastModified() < o2.lastModified()) {
                    return 1;
                }
                if (o1.lastModified() > o2.lastModified()) {
                    return -1;
                }
                return 0;
            };
        }
    
        private static void createDummyFiles(ArrayList<File> files) throws IOException {
            long timestamp = System.currentTimeMillis();
            int filesToCreate = 30;
            for (int i = 0; i < filesToCreate; i++) {
                long lastModified = timestamp + 5 * i;
                String fileName = String.format("foobar_%02d", i);
                File file = new File(fileName);
                file.createNewFile();
                file.setLastModified(lastModified);
                files.add(file);
            }
        }
    }
    

    【讨论】:

    • 在示例中我们可以使用.sorted(Comparator.comparing(File::lastModified).reversed()),而不是使用自定义比较器.sorted(getReverseLastModifiedComparator())
    【解决方案2】:
    Arrays.asList(dir.listFiles()).stream()
                .filter(file -> isNameLikeBaseLine(file, baseLineFile.getName()))
                .sorted(new Comparator<File>() {
                    @Override
                    public int compare(File o1, File o2) {
                        int answer;
                        if (o1.lastModified() == o2.lastModified()) {
                            answer = 0;
                        } else if (o1.lastModified() > o2.lastModified()) {
                            answer = -1;
                        } else {
                            answer = 1;
                        }
                        return answer;
                    }
                }).limit( 10 );
    

    【讨论】:

    • 答案不正确,因为limit(10) 将返回十个最旧的文件。 Comparator 中的返回值应交换(o1.lastModified() > o2.lastModified() 返回 -1,默认返回 1)以相反的顺序返回值,limit(10) 应替换为 skip(10) 到跳过十个最新的文件并返回剩余的要删除的文件。
    • @user1065869 我承认我并没有仔细研究过compare
    • @SubOptimal 感谢您的检查。但是 skip 会跳过 10,这不能保证会留下 10。但是改变比较的顺序应该可以解决问题。
    • 由于流应该按降序返回值(请参阅我的第一条评论),前十个元素是具有最新最后修改时间戳的文件。所以我们需要跳过它们并返回剩余的文件。
    • @SubOptimal 啊,“过滤器”(“想要过滤 10 个最近的文件”)的永恒可疑的含义。使用“过滤咖啡”您想要咖啡,使用“黄金过滤器”(牙医!)您想要黄金。 ;-)
    【解决方案3】:

    尝试使用limit(10);正确排序后

    另一种方法是使用 skip(10) 和 forEach( f--> removefile(f) )。我认为它更适合。

    【讨论】:

    • 但我想要反向选择。我想留下这 10 个文件。并删除所有其他(不知道有多少)
    • 更改比较器以进行反向选择
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 2020-11-07
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多