按数字顺序对文件进行排序

2024-03-12

我编写了一个程序将文件夹中的所有文件组合在一起。

这是我的代码的一部分:

File folder = new File("c:/some directory");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles){

if (file.isFile()){
    System.out.println(file.getName());
    File f = new File("c:/some directory"+file.getName());

但是,我希望我的文件可以按以下顺序排列: 作业1.脚本,作业2.脚本,......

但我得到: job1.script、job10.script、job11.script,即 10,11,12... 在 2 前面。

我希望我能得到有效的代码来避免这个问题。


是时候摆脱所有笨拙的代码并使用 Java 8 了!这个答案还包括Pathclass 已经是 Java 7 的一部分,但在 Java 8 中似乎得到了很大的改进。

代码:

private void init() throws IOException {
    Path directory = Paths.get("C:\\Users\\Frank\\Downloads\\testjob");
    Files.list(directory)
            .filter(path -> Files.isRegularFile(path))
            .filter(path -> path.getFileName().toString().startsWith("job"))
            .filter(path -> path.getFileName().toString().endsWith(".script"))
            .sorted(Comparator.comparingInt(this::pathToInt))
            .map(path -> path.getFileName())
            .forEach(System.out::println);
}

private int pathToInt(final Path path) {
    return Integer.parseInt(path.getFileName()
            .toString()
            .replace("job", "")
            .replace(".script", "")
    );
}

的解释pathToInt:

  1. 从给定的Path,获取文件的字符串表示形式。
  2. Remove "job" and ".script".
  3. 尝试将字符串解析为整数。

的解释init,主要方法:

  1. 获得一个Path到文件所在的目录。
  2. 获取惰性填充列表Path目录中的 s,请注意:这些Path还是完全有资格的!
  3. 保留常规文件。
  4. 保留最后部分的文件Path,因此是文件名(例如job1.script) 以。。开始"job". Be aware您需要首先获得的字符串表示Path在你可以检查它之前,否则你将检查整个Path从一个名为的目录开始"job".
  5. 对以以下结尾的文件执行相同操作".script".
  6. 现在有趣的地方来了。这里我们根据a对文件列表进行排序Comparator比较我们通过调用获得的整数pathToInt on the Path。这里我使用的是方法参考,方法comparingInt(ToIntFunction<? super T> keyExtractor需要一个映射 a 的函数T,在这种情况下Path,到一个整数。这正是pathToInt确实如此,因此它可以用作方法参考。
  7. 然后我映射每个Path to the Path仅由文件名组成。
  8. 最后,对于每个元素Stream<Path>, 我打电话System.out.println(Path.toString()).

看起来这段代码可以写得更容易,但我故意把它写得更详细。我这里的设计是保持完整Path始终完好无损,代码的最后一部分forEach实际上违反了该原则,因为在它仅映射到文件名之前不久,因此您无法处理完整的内容Path稍后再讲。

该代码还被设计为快速失败,因此它期望文件以以下形式存在job(\D+).script,并且会抛出一个NumberFormatException如果情况并非如此。

输出示例:

job1.script
job2.script
job10.script
job11.script

可以说,更好的替代方案具有正则表达式的强大功能:

private void init() throws IOException {
    Path directory = Paths.get("C:\\Users\\Frank\\Downloads\\testjob");
    Files.list(directory)
            .filter(path -> Files.isRegularFile(path))
            .filter(path -> path.getFileName().toString().matches("job\\d+.script"))
            .sorted(Comparator.comparingInt(this::pathToInt))
            .map(path -> path.getFileName())
            .forEach(System.out::println);
}

private int pathToInt(final Path path) {
    return Integer.parseInt(path.getFileName()
            .toString()
            .replaceAll("job(\\d+).script", "$1")
    );
}

这里我使用正则表达式"job\\d+.script",它匹配以以下开头的字符串"job",后跟一位或多位数字,然后是“.script”。
我使用几乎相同的表达方式pathToInt方法,但是我使用了捕获组、括号和$1使用该捕获组。

我还将提供一种简洁的方法来读取一个大文件中的文件内容,正如您在问题中所问的那样:

private void init() throws IOException {
    Path directory = Paths.get("C:\\Users\\Frank\\Downloads\\testjob");
    try (BufferedWriter writer = Files.newBufferedWriter(directory.resolve("masterjob.script"))) {
        Files.list(directory)
                .filter(path -> Files.isRegularFile(path))
                .filter(path -> path.getFileName().toString().matches("job\\d+.script"))
                .sorted(Comparator.comparingInt(this::pathToInt))
                .flatMap(this::wrappedLines)
                .forEach(string -> wrappedWrite(writer, string));
    }
}

private int pathToInt(final Path path) {
    return Integer.parseInt(path.getFileName()
            .toString()
            .replaceAll("job(\\d+).script", "$1")
    );
}

private Stream<String> wrappedLines(final Path path) {
    try {
        return Files.lines(path);
    } catch (IOException ex) {
        //swallow
        return null;
    }
}

private void wrappedWrite(final BufferedWriter writer, final String string) {
    try {
        writer.write(string);
        writer.newLine();
    } catch (IOException ex) {
        //swallow
    }
}

请注意,lambda 不能抛出/捕获检查Exceptions,因此有必要在代码周围编写包装器,以决定如何处理错误。吞掉异常很少是一个好主意,我只是在这里简单地使用它来编写代码。

这里真正的大变化是,我没有打印出名称,而是将每个文件映射到其内容并将它们写入文件中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按数字顺序对文件进行排序 的相关文章

随机推荐

  • ContinueWith TaskContinuationOptions.OnlyOnFaulted 似乎没有捕获从已启动任务引发的异常

    我正在尝试使用 ContinueWith 和 OnlyOnFaulted 捕获从任务方法引发的异常 如下所示 但是 当我尝试运行此代码时 出现未处理的异常 我希望任务能够完成 因为我已经处理了异常 但是 Task Wait 遇到 Aggre
  • Angular4 项目上字体很棒的图标未加载

    我正在使用 font awesome 开发 Angular 4 项目 我按照本指南使用 npm 安装库 如何将 font awesome 添加到 Angular 2 CLI 项目 https stackoverflow com questi
  • 根据多个任意模式验证 XML

    考虑一个具有多个模式的 XML 文档 其开头如下所示 这不是 Spring 特定的问题 这只是示例的一个方便的 XML 文档
  • 为什么 GetAttr 不适用于 cloudformation 模板参数?

    拥有父子关系中的 cloudformation 模板集合 并希望将 AWS IAM Role 传递到子堆栈的参数中 并使用 GetAttr 获取 Arn 这会导致验证失败 因为只能对资源调用 GetAttr 而不能对参数调用 有人知道 猜猜
  • 当服务器在Linux中启动时,Spring Boot出现错误

    首先 有两个Linux服务器 我想建立一个冗余的web server在两台服务器上 我在两台服务器上均等地安装了jre1 8 0 并且我在两台服务器上均等地安装了相同的spring boot war文件 顺便一提 服务器1正常启动并正常工作
  • 如何在 ruby​​ on Rails 中调用存储过程?

    我是 ROR 新手 我想在单击 VIEW 中的提交按钮时调用存储过程进行处理 Model class Pro DataImport lt ActiveRecord Base attr accessible file name process
  • NamedPipe 多个服务器

    对于简单的 IPC 我选择了 NamedPipes 在进程 本地 之间进行通信 由于需求的变化 应该有多个服务器实例 这会导致同一管道名上有多个 侦听器 但似乎有一个问题 这些侦听器中只有一个会收到消息 其他所有实例都不会收到消息 有某种
  • Python 从装饰器导入模块

    我正在使用 Python 3 开发一个应用程序 而且我所做的事情是非常规的 cx Oracle 是一个很难设置的模块 对于我的应用程序来说是一个可选的依赖项 我想做的是将模块的导入包装在装饰器中 仅放置在使用它的函数之上 这将避免必须在我的
  • 递增循环的致命错误

    目前 我正在尝试创建一个函数 在 Fighter cpp 文件中的函数 sortFighters 中对充满战斗机的向量进行排序 一切似乎都可以正确编译 但是 当它运行时 我在上述 cpp 文件的某一行中收到致命错误 我确切地知道问题是什么
  • 未添加 NuGet 包的参考

    我有一个自定义 NuGet 包 My Resources 其中包含程序集和对另一个自定义 NuGet 包 My Base 的依赖项 如果我安装该软件包 安装会成功完成 但不会添加程序集引用 这是完整的输出Install Packagecom
  • 矩阵列表乘以标量,Rcpp 中不保留维度属性

    我正在使用 Rcpp 来加速一些 R 代码 实际上这是我 2014 年 待办事项 列表中的项目之一 部分代码包括将矩阵列表乘以标量 我能够得到结果 尽管如此 矩阵不再是矩阵 而是向量 我想要一个矩阵列表作为最终输出 这是我到目前为止的代码
  • htaccess 重定向百分号

    我遇到了 htaccess redirect 问题 在搜索了近一个小时后无法解决 请帮我 RewriteRule yeah http www domain de awesome 123123 NC QSA L R 301 所以我想从doma
  • 从 futures::Stream 转发到 futures::Sink

    我目前正在尝试了解 tokio futures 原语和生态系统 我开始做一些工作tk http websocket 示例 https github com swindon rs tk http blob abfdb50a00ab90b4f0
  • 在 C# 中导入 DLL

    我正在尝试使用 DllImport 将 dll 导入到我的 C 项目 如下所示 DllImport kernel32 private static extern long WritePrivateProfileString string s
  • 使用 HTML / CSS 显示/隐藏带有复选框的特定 Div

    我正在尝试找出一种方法来链接特定的复选框以显示 隐藏specificdiv 元素 我能够找到显示 隐藏 Div 元素的复选框的代码紧接在下面他们 但我想知道是否有一种方法可以将特定的复选框链接到我选择的任何 div 在我的代码中 我基本上想
  • 如何在 R 中获得 ping 响应

    我有一个包含域名列的数据框 我想通过 ping 域名来查看存在哪个域 我可以从以下函数获得单独的 ping 响应 ping lt function x stderr FALSE stdout FALSE pingvec lt system2
  • 应用自动调整大小时旋转期间 iOS8 MKMapView 帧缓冲区错误

    import AppDelegate h import
  • 如何将 gettext 与 python >3.6 f 字符串一起使用

    以前你会使用gettext如下 Hey format username 但是新的 Python 的 f 字符串呢 f Hey username Hey 按原样包含在您的翻译词典中 如果你使用f Hey username 这会创建另一个不会被
  • 如果父对象不是单例,那么子对象也是单例吗?

    我有一个不是单例的 Dao 从他扩展的其他对象 是否是单例 代码示例
  • 按数字顺序对文件进行排序

    我编写了一个程序将文件夹中的所有文件组合在一起 这是我的代码的一部分 File folder new File c some directory File listOfFiles folder listFiles for File file