javajava-nio

Does StandardOpenOption.APPEND require StandardOpenOption.WRITE?


According to the documentation, StandardOpenOption.APPEND seems it requires the StandardOpenOption.WRITE.

If the file is opened for WRITE access then bytes will be written to the end of the file rather than the beginning.

If the file is opened for write access by other programs, then it is file system specific if writing to the end of the file is atomic.

Is it true?

I tested with StandardOpenOption.APPEND only, and it works.

@Test
void __(@TempDir final Path dir) throws Exception {
    final var path = Files.createTempFile(dir, null, null);
    final var b = ByteBuffer.allocate(12);
    try (var channel = FileChannel.open(path, StandardOpenOption.APPEND)) {
        while (b.hasRemaining()) {
            channel.write(b);
        }
        channel.force(true);
    }
    Assertions.assertEquals(Files.size(path), b.capacity());
}

What does the comment mean?

If the file is opened for WRITE access then bytes will be written to the end of the file rather than the beginning.


Solution

  • Does StandardOpenOption.APPEND require StandardOpenOption.WRITE?

    Yes and no.

    Yes - the semantics of APPEND are only defined for a channel opened with the WRITE option. And that definition only makes sense for a write (or read-write) channel.

    No - the spec doesn't require WRITE if APPEND is supplied. And there don't seem to be any checks in the code to validate this (supposed) constraint.

    As far as I can tell, APPEND on a READ channel will simply be ignored. And your test suggests that the APPEND option implies the WRITE option ... at least, on the platform on which you tested. That behavior makes sense to me. But either way, this is outside of the specification.