开发者

How to set position properly in NIO.2's AsynchronousFileChannel.write(ByteBuffer src, long position)?

开发者 https://www.devze.com 2023-03-30 00:05 出处:网络
My Java-program does a multithreaded XSLT Transformation and writes the resul开发者_JAVA百科ts to a file. To avoid the IO bottleneck I am experimenting with the new AsynchronousFileChannel.

My Java-program does a multithreaded XSLT Transformation and writes the resul开发者_JAVA百科ts to a file. To avoid the IO bottleneck I am experimenting with the new AsynchronousFileChannel. The XSLT-Threads should submit their output as strings (which works) and the Writer to append them to the file (that does not work yet).

I wrote a custom Writer-class for the write-operations. My Threads call the Writer.write(String text)-method. In there I would like to append the String as ByteBuffer to the AsynchronousFileChannel. Unfortunately, I could find no hint what to use as the position value in asyncOutput.write(ByteBuffer, Long). I tried different values for position without success (Output gets scrambled). I am pretty sure, there is no problem with synchronization as the code works well with FileChannels (which do not support a simple non blocking io mode):

  • asyncOutput.size()
  • asyncOutput.size() + future.get().longValue()
  • 0

Here's the code how I am trying to do this:

public class MyWriter {
private AsynchronousFileChannel asyncOutput;    

    MyWriter(String filename) throws IOException {
        asyncOutput = AsynchronousFileChannel.open(Paths.get(filename), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
    }

    public void write(String output) throws IOException, ExecutionException, InterruptedException {
        System.err.println("Write was called");
        this.future = asyncOutput.write(string2ByteBuffer(output), asyncOutput.size());
    }

    public ByteBuffer string2ByteBuffer (String text){
    ...
    }
}

The method is called from a the XSLT-Threads (Runnable) like this:

synchronized (this) {
        this.write2Writer(outputXmlWriter.toString());
        }
...
private void write2Writer(String output) throws IOException {
    try {
        myWriter.write(output);
    } catch (ExecutionException | InterruptedException ex) {
        ex.printStackTrace();
    }
}


I could find no hint what to use as the position value in asyncOutput.write(ByteBuffer, Long)

It is the position you want to position at. I don't see what's so mysterious about it.


AsynchronousFileChannel does not have a global position, this is deliberate. Instead this channel provides an asynchronous API for applications that need to access different parts of a file at the same time.


The solution extracted from the link:

Future<Integer> future = asyncOutput.write(string2ByteBuffer(output), this.position);
this.position += future.get();

Source: http://cr.openjdk.java.net/~alanb/6830721/webrev.00/test/java/nio/channels/AsynchronousFileChannel/Basic.java.html

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号