Search code examples
javafilesynchronizationfilesystemsnio

Does java.nio.file.Files.copy call sync() on the file system?


i'm developing an application that has to reboot the system after a file has been uploaded and verified. The file system is on an sd card, so it must be synced to be sure the uploaded file has actually been saved on the device.

I was wondering if java.io.file.Files.copy does the sync or not.

My code runs like this:

public int save(MultipartFile multipart) throws IOException {

    Files.copy(multipart.getInputStream(), file, standardCopyOption.REPLACE_EXISTING);

    if (validate(file)) {
        sync(file); <-- is it useless?
        reboot();
        return 0;
    } else {
        Files.delete(file);
        return -1;
    }
}

I tried to find a way to call sync on the fs in the nio package, but the only solution that i've found is:

public void sync(Path file) {
    final FileOutputStream fos = new FileOutputStream(file.toFile());
    final FileDescriptor fd = fos.getFD();
    fd.sync();
}

which relies on old java.io.File .


Solution

  • If you look at the source code for Files.copy(...), you will see that it doesn't perform a sync(). In the end, it will perform a copy of an input stream into an output stream corresponding to the first 2 arguments passed to Files.copy(...).

    Furthermore, the FileDescriptor is tied to the stream from which it is obtained. If you don't perform any I/O operation with this stream, other than creating a file with new FileOutputStream(...), there will be nothing to sync() with the fie system, as is the case with the code you shared.

    Thus, the only way I see to accomplish your goal is to "revert" to the old-fashioned java.io API and implement a stream-to-stream copy yourself. This will allow you to sync() on the file descriptor obtained from the same FileOutputStream that is used for the copy operation.