Search code examples
javanio

I'm Confused with Java NIO


I'm confused with java nio buffers and Files.write if I can write with buffers and channels on file why do I need Files class.

What's difference between both of these working code examples.

String newData = "New String to write to file..." + System.currentTimeMillis();

Path path = Paths.get("C://data/nio-data2.txt");
try {
    Files.write(path,newData.getBytes());
} catch (IOException e) {
    e.printStackTrace();
}

and

try {
    RandomAccessFile aFile = new RandomAccessFile("C://data/nio-data.txt", "rw");
    FileChannel channel = aFile.getChannel();
    ByteBuffer buf = ByteBuffer.allocate(48);
    buf.clear();
    buf.put(newData.getBytes());

    buf.flip();

    while(buf.hasRemaining()) {
        channel.write(buf);
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

EDIT

i want to ask one more question, is Channels.newOutputStream interrupt the thread when write to file or worked as a non-blocking


Solution

  • Version with Files shorter and easier to understand.

    Other version is more flexible. It is not very useful when you have only one file to write, but if you have many files in different storages it can save you some resources.

    EDIT

    Here is Files.write source code:

    public static Path write(Path path, byte[] bytes, OpenOption... options)
        throws IOException
    {
        // ensure bytes is not null before opening file
        Objects.requireNonNull(bytes);
    
        try (OutputStream out = Files.newOutputStream(path, options)) {
            int len = bytes.length;
            int rem = len;
            while (rem > 0) {
                int n = Math.min(rem, BUFFER_SIZE);
                out.write(bytes, (len-rem), n);
                rem -= n;
            }
        }
        return path;
    }
    

    As you can see it doesn't use NIO inside, only good old OutputStream.

    EDIT 2

    In fact Files.newOutputStream don't return FileOutputStream as I expected. It returns OutputStream defined in Channels.newOutputStream which use NIO inside.