Search code examples
javaniofilechannel

What's the alternative for BufferedWriter in Java NIO


If we are using Java Standard IO api's to read a file line by line and manipulate line and write it to a new file. We would be using a snippet something like this.

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
String str;
while ((str = br.readLine()) != null) {
    //... code for manipulation of str
    bw.write(str);
    bw.newLine();
}

I require a readlock on the file that is getting written, So I proceeded to use FileChannel in Java NIO package. In order to achieve the same. The code snippet I have written is below.

int blocksize = 32 * 1024;
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFilePath), inputCharset));
FileOutputStream fos = new FileOutputStream(outputFilePath);
FileChannel outputFileChannel = fos.getChannel();
outputFileChannel.lock();
ByteBuffer buffer = ByteBuffer.allocate(blocksize);
while((line=br.readLine())!=null){
    buffer.put(line.getBytes(StandardCharsets.UTF_8));
    buffer.put("\n".getBytes(StandardCharsets.UTF_8));
    buffer.flip();
    outputFileChannel.write(buffer);
    buffer.clear();
}
br.close();
outputFileChannel.close();
fos.close(); 

Now my question is how much this is affecting performance, is Filechannel would be writing to file everytime we call filechannel.write (I mean is it exactly behaves like filereader.write)or will it be internally using a buffer.


Solution

  • I would use BufferedWriter and FileChannel.lock().

    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
    FileLock lock = fis.getChannel().lock();
    
    BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
    String str;
    while ((str = br.readLine()) != null) {
        //... code for manipulation of str
        bw.write(str);
        bw.newLine();
    }
    lock.release();