首页 > 解决方案 > 使用Java按数字顺序返回目录中的文件名

问题描述

我们有一种情况,我们的目录中的文件带有前缀(比如MyFile),后跟一个数字(例如 MyFile1、MyFile2、MyFile3,...)。我们希望返回目录中的文件名列表,但按数字顺序。例如 MyFile1、MyFile2、MyFile3、...、MyFile9、MyFile10、MyFile11、MyFile12 等)。

JavaFilelist()方法返回文件名列表,但按字典顺序(MyFile1、MyFile10、MyFile11、MyFile12、MyFile2、MyFile3...、MyFile9 等)。是否有 API 调用可以按照我们想要的顺序返回文件名?


附录Java File.list()
中建议的解决方案的轻微变体是否一致?对我有用。我创建了一个名为. 代码如下:generateConsistentOrder

protected void generateConsistentOrder(String[] files, String prefixToDrop) {
        Arrays.sort(
                files,
                new Comparator<String>() {
                    public int compare(String a, String b) {
                        Integer retVal = null;
                        try {
                            Integer intA = Integer.parseInt(a.substring(a.indexOf(prefixToDrop)+prefixToDrop.length()));
                            Integer intB = Integer.parseInt(b.substring(b.indexOf(prefixToDrop)+prefixToDrop.length()));
                            retVal = intA.compareTo(intB);
                        }
                        catch (Exception e) {
                            retVal = a.compareTo(b);
                        }

                        return retVal;
                    }
                });
    }

标签: java

解决方案


您可以做的是使用Files#list来自java.nio包的方法。有了这些,您最终将得到一个Path对象流,可以在其上应用一个Comparator将使用Path#getFileName.

使用 than in place 你需要有一个Comparator接口的实现,它将从给定的文件路径中刮取数字并将值与其他值进行比较。一个简单的例子是这样的:


public class PathComparator implements Comparator<Path> {

    private static final Pattern PATTERN = Pattern.compile("\\d+");

    @Override
    public int compare(Path o1, Path o2) {
        var path1Matcher = PATTERN.matcher(o1.getFileName().toString());
        var path2Matcher = PATTERN.matcher(o2.getFileName().toString());
        Integer file1 = 0;
        Integer file2 = 0;
        if (path1Matcher.find()) {
            file1 = Integer.valueOf(path1Matcher.group());
        }

        if (path2Matcher.find()) {
            file2 = Integer.valueOf(path2Matcher.group());
        }
        return file1.compareTo(file2);
    }

}

将它们放在一起看起来像这样:

public static List<Path> listOrdered(String path) {
    try (var fileStream = Files.list(Paths.get(path))) {
        return fileStream
            .sorted(new PathComparator())
            .toList();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return Collections.emptyList();
}

请注意,我在此示例中使用 Java 16,但您可以轻松修改它以使用较旧的 Java 版本。


推荐阅读