如何在NIO.2的AsynchronousFileChannel.write(ByteBuffer src, long position)中正确设置位置?

发布于 2024-11-30 22:10:00 字数 1532 浏览 0 评论 0 原文

我的 Java 程序执行多线程 XSLT 转换并将结果写入文件。为了避免 IO 瓶颈,我正在尝试新的 AsynchronousFileChannel。 XSLT-Threads 应该将其输出作为字符串提交(这可以工作),而 Writer 应该将它们附加到文件中(这还不能工作)。

我为写操作编写了一个自定义 Writer 类。我的线程调用 Writer.write(String text) 方法。在那里,我想将字符串作为 ByteBuffer 附加到 AsynchronousFileChannel。 不幸的是,我找不到在 asyncOutput.write(ByteBuffer, Long) 中使用什么作为位置值的提示。我尝试了不同的位置值但没有成功(输出被扰乱)。我很确定,同步没有问题,因为代码可以很好地与 FileChannels 配合使用(不支持简单的非阻塞 io 模式):

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

这是我尝试执行此操作的代码:

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){
    ...
    }
}

从 XSLT 线程(可运行)调用该方法,如下所示:

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

My Java-program does a multithreaded XSLT Transformation and writes the results 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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

趴在窗边数星星i 2024-12-07 22:10:00

我找不到任何提示来使用什么作为位置值
asyncOutput.write(ByteBuffer, Long)

这是你想要定位的位置。我不明白这有什么神秘的。

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.

巴黎盛开的樱花 2024-12-07 22:10:00

AsynchronousFileChannel 没有全局位置,这是故意的。相反,此通道为需要同时访问文件不同部分的应用程序提供异步 API。

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.

胡渣熟男 2024-12-07 22:10:00

从链接中提取的解决方案:

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文