【发布时间】:2023-03-22 18:10:02
【问题描述】:
在一个要求中,我需要将多个文件从一个位置复制到另一个网络位置。
假设我在/src 位置存在以下文件。a.pdf, b.pdf, a.doc, b.doc, a.txt and b.txt
我需要立即将a.pdf, a.doc and a.txt 文件atomically 复制到/dest 位置。
目前我正在使用 Java.nio.file.Files 包和代码如下
Path srcFile1 = Paths.get("/src/a.pdf");
Path destFile1 = Paths.get("/dest/a.pdf");
Path srcFile2 = Paths.get("/src/a.doc");
Path destFile2 = Paths.get("/dest/a.doc");
Path srcFile3 = Paths.get("/src/a.txt");
Path destFile3 = Paths.get("/dest/a.txt");
Files.copy(srcFile1, destFile1);
Files.copy(srcFile2, destFile2);
Files.copy(srcFile3, destFile3);
但是这个过程文件是一个接一个地复制的。
作为对此的替代,为了使整个过程成为原子的,
我正在考虑压缩所有文件并移动到/dest 并在目的地解压缩。
这种方法是否可以使整个复制过程成为原子的?任何人都遇到过类似的概念并解决了它。
【问题讨论】:
-
您也可以一个一个地复制它们,首先使用 .tmp 文件扩展名,然后重命名它们。但是你的目标是什么?
-
@J.Doe 一个一个地复制多个文件不是原子操作权。考虑一个事务,其中多个表的数据存储在一个镜头中,我想要在这里。
-
我不认为有一种方法可以获得纯粹的原子性,保证你要么得到你想要的东西,要么对文件系统没有任何变化。但是你可以做一些类似@J.Doe 建议的事情。我有类似的想法,但我的想法是首先将文件复制到您真正想要复制它们的目录中的隐藏目录。然后你会在复制后将它们移动到位。您可以非常有信心这 3 个动作会成功并快速奏效,但仍然会有很短的时间,其中只有 1 或 2 个文件。
-
如果您希望上述场景作为单个事务发生,我建议您使用 Java 8 中引入的 Stream API。首先,为每个文件插入字节流,以Stream 对象中的字符,然后通过网络发送它。到达目标位置后,您可以遍历 Stream 对象并将每个字节流插入到一个位置。此外,如果您需要维护文件格式(.docx、.pdf、.txt),您应该使用定义为
Map<ByteArrayInputStream, String>的 Map 对象并将此 Map 对象作为 Stream 对象通过网络发送。 -
您的 zip 和 copy 解决方案是正确且原子的,因此当出现单个问题时,目标目录中不会出现任何文件。只要确保你在临时目录中压缩你的文件
标签: java spring java.nio.file