Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java FileChannel.write: finish the buffer before reporting success

Last updated: 5 Oct 20265 min read
tutorial
AdvancedBy AITrove Editorial

A FileChannel.write call advances a ByteBuffer by the number of bytes it actually wrote. A caller that needs the entire payload must loop until the buffer has no remaining bytes.

Operational contract

The channel is opened with CREATE_NEW so an existing manifest cannot be overwritten by this helper. The buffer wraps bytes already owned by the caller; the caller must not mutate that array during the write. A zero-byte write is treated as lack of progress rather than an excuse to spin forever. Closing the channel releases its handle but is not the same as an explicit durability request. If the write fails halfway, a partial new file may remain; the caller owns cleanup or should stage to a temporary name before publication.

Failure case

A receipt batch is encoded into 47,000 bytes. One write returns after 16,384 bytes. Treating that return as completion publishes a truncated batch. The loop continues from the buffer's new position and only returns after all bytes have been accepted by the channel. It still does not claim that the data survived a power failure.

Java code

Java
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class ManifestChannelWriter {
    public static void create(Path destination, byte[] payload) throws IOException {
        try (FileChannel channel = FileChannel.open(destination,
                StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
            ByteBuffer pending = ByteBuffer.wrap(payload);
            while (pending.hasRemaining()) {
                if (channel.write(pending) == 0) throw new IOException("Channel made no write progress");
            }
        }
    }
}

Performance and ownership cost

The loop writes B bytes in O(B) I/O work and uses O(1) extra application storage because ByteBuffer wraps the caller's array. Device and filesystem costs dominate. A staged publish adds another file operation but prevents readers from opening a half-written final name.

Common Mistakes

  • Do not assume one write drains a ByteBuffer.
  • Do not mutate the wrapped byte array during the write.
  • Do not call close alone a full durability or publication guarantee.

Connected lessons

java
file channel boundaries
filechannel-write-completion
Storage details