简体   繁体   English

(Java NIO) 在通道之间复制时,我应该检查读取的字节和缓冲区 position 吗?

[英](Java NIO) Should I check both bytes read and buffer position in copying between channels?

This code is similar to example code in the JavaDoc of ByteBuffer.compact()此代码类似于 ByteBuffer.compact() 的 JavaDoc 中的示例代码

package com.study.nio;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;

public class BufferCopy {

    public static void main(String[] args) {
        var from = "Hello World".getBytes();

        var buf = ByteBuffer.allocate(5);
        buf.clear();
        try (var outputStream = new ByteArrayOutputStream();
             var inChannel = Channels.newChannel(new ByteArrayInputStream(from));
             var outChannel = Channels.newChannel(outputStream);) {
            while (inChannel.read(buf) >= 0 || buf.position() != 0) {
                buf.flip();
                outChannel.write(buf);
                buf.compact();
            }
            System.out.println(outputStream.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

My question is do we need the "|| buf.position() !=0" in the while condition check?我的问题是我们是否需要在 while 条件检查中使用“|| buf.position() !=0”

Just for reference, the code example provided in the documentation of Buffer.compact() is this:仅供参考, Buffer.compact()文档中提供的代码示例如下:

   buf.clear();          // Prepare buffer for use
   while (in.read(buf) >= 0 || buf.position != 0) {
       buf.flip();
       out.write(buf);
       buf.compact();    // In case of partial write
   }

Scenario 1: Condition is Finally Met场景 1:条件终于满足

  • Now, picture the moment when the channel in reaches its EOF and it adds its final 100 bytes to the buffer buff .现在,想象一下通道in达到其 EOF 并将其最后 100 个字节添加到缓冲区buff的时刻。
  • The code enters the while loop because in.read(buff) >= 0 , the second condition is not even evaluated.代码进入 while 循环,因为in.read(buff) >= 0 ,甚至没有评估第二个条件。
  • Now while writing out.write(buff) only 50 of the 100 bytes in the buffer are sent (perhaps the output channel has a very low bandwidth or its buffer is too small).现在在写out.write(buff)时,仅发送缓冲区中 100 个字节中的 50 个(可能 output 通道的带宽非常低或者其缓冲区太小)。
  • The buffer is compacted (pos=50,limit=100,cap=100).缓冲区被压缩(pos=50,limit=100,cap=100)。
  • Now, the while condition is evaluated again, this time in.read(buff) >= 0 is false because in channel is at its EOF, so it evaluates buf.position != 0 and we discover that there are still bytes in the buffer.现在,再次评估 while 条件,这次in.read(buff) >= 0为假,因为in通道处于其 EOF,因此它评估buf.position != 0并且我们发现缓冲区中仍有字节.
  • So, it goes back into the while loop and writes a few more bytes into the output channel.因此,它返回到 while 循环并将更多字节写入 output 通道。

Scenario 2: Slow Output Building up场景 2:缓慢 Output 建立

Another way to look at how this condition gradually builds up is by picturing a scenario when the output channel is slower than the input channel, eg low bandwidth and/or a smaller output buffer.了解这种情况如何逐渐建立的另一种方法是通过想象 output 通道比输入通道慢的场景,例如低带宽和/或较小的 output 缓冲区。

  • The code enters the while loop because in.read(buff) >= 0 , the second condition is not even evaluated.代码进入 while 循环,因为in.read(buff) >= 0 ,甚至没有评估第二个条件。 It reads 100 bytes.它读取 100 个字节。
  • Now while writing out.write(buff) only 50 of the 100 bytes in the buffer are sent.现在在写out.write(buff)时,缓冲区中的 100 个字节中只有 50 个被发送。
  • The buffer is compacted (pos=50,limit=100,cap=100).缓冲区被压缩(pos=50,limit=100,cap=100)。
  • Now, the while condition is evaluated again, and this time in.read(buff) >= 0 adds 50 more bytes into the buffer and we are once again at 100 bytes total.现在,再次评估 while 条件,这一次in.read(buff) >= 0将 50 个字节添加到缓冲区中,我们再次达到总共 100 个字节。
  • The while repeats in this fashion until the scenario 1 is reached once more buf.position != 0 is finally evaluated. while 以这种方式重复,直到再次达到场景 1 buf.position != 0最终被评估。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM