zblash
zblash

Reputation: 133

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

Upvotes: 1

Views: 502

Answers (2)

talex
talex

Reputation: 20455

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.

Upvotes: 2

ZhenyaM
ZhenyaM

Reputation: 686

  1. Files.write(...) use OutputStream instead of RandomAccessFile.getChannel(). it some different mechanisms, so better to google it for understand

  2. Files.write(...) much shorter and incapsulate logic of writting to file

  3. When you use such 'low' code, you need to look after many things. For example, in your example you didn't close your channel.

So, in conclusion, if you need to just write – better to use Files or another high-level API. If you need some 'additional' features during read/write, you need to use RandomAccessFile or InputStream/OutputStream

Upvotes: 1

Related Questions