1

有一些解决方法,但我想提出一个与真实事物有关的问题。

我有一个外部服务器将文件上传到 /upload 文件夹,我正在使用 java.nio.file.Files 原子移动将它们复制到 /dest 文件夹中,然后处理移动的文件。

问题是很明显,在调用 nio move 之后,源文件尚未在源中刷新,但仍以原子方式执行 move,一旦刷新,它就会刷新到目标移动文件。

操作系统是 Ubuntu。伪是:

Path origFilePath = resolveOrigFilePath();
Path targetFilePath = resolveOrigFilePath();

//记录显示源中的空文件,长度= 0

   logger.warn("Atomic move file [{}], can read mode: [{}],can write mode: [{}] source size: [{}]",
            origFilePath, origFilePath.toFile().canRead(), origFilePath.toFile().canWrite(), origFilePath
                    .toFile().length());

//执行文件的原子移动

    Path target = Files.move(origFilePath, targetFilePath, StandardCopyOption.ATOMIC_MOVE);

//记录显示空文件已移动,原始文件不再存在

    logger.warn(
            "Atomic moved file [{}] to [{}], target read mode: [{}], target write mode: [{}], target size: [{}], orig target size: [{}], is original exists [{}]",
            origFilePath, target, target.toFile().canWrite(), target.toFile().canRead(),
            target.toFile().length(), targetPath.toFile().length(), sensorFilePath.toFile().exists());

. . //处理仍然为空的目标文件。. //在一小段时间后目标文件有内容,而没有其他程序访问该文件

. .

知道底层实现的原因是什么吗?

4

1 回答 1

0

在您开始移动文件之前,请确保您这样做OutputStream.flush(),更重要的是FileDescriptor.sync()

        FileOutputStream out = new FileOutputStream(file, false);

        // Write your data here.

        out.flush();

        FileDescriptor fd = out.getFD();
        fd.sync();

        out.close();
于 2019-11-06T17:54:28.300 回答