[英]Java NIO. Why flip() method breaks my program?
Java code below: 下面的Java代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class Test {
public static void main(String args[]) throws IOException {
SocketChannel c = SocketChannel.open();
c.connect(new InetSocketAddress("google.com", 80));
ByteBuffer b = ByteBuffer.allocate(1024);
b.put("Request".getBytes());
System.out.println("Write: " + c.write(b));
int i;
while ((i = c.read(b)) != -1) {
System.out.println("Read: " + i);
b.clear();
}
}
}
Actual Result: 实际结果:
Write: 1017 Read: 0 Read: 1024 Read: 44
写:1017读:0读:1024读:44
First time, method read()
read 0 bytes. 第一次,方法
read()
读取0个字节。 It is not cool. 这不酷。
I modified my code: 我修改了代码:
b.put("Request".getBytes());
System.out.println("Write: " + c.write(b));
b.flip(); //I added this line
int i;
while ((i = c.read(b)) != -1) {
System.out.println("Read: " + i);
b.clear();
}
Actual results: 实际结果:
Write: 1017 Read: 1024 Read: 44
写:1017读:1024读:44
It already looks better. 它看起来已经更好了。 Thanks
flip()
for this! 感谢
flip()
!
Next, I put to buffer String "Request" , this String has length 7 , but method write()
returned 1017 . 接下来,我将缓冲区字符串“ Request”放入缓冲区,该字符串的长度为7 ,但是方法
write()
返回1017 。
What information method wrote to channel? 哪种信息方法写给渠道?
I am not sure, that method wrote string "Request" . 我不确定,该方法写了字符串“ Request” 。
Ok, I modified my code again: 好的,我再次修改了代码:
b.put("Request".getBytes());
b.flip(); // I added this line
System.out.println("Write: " + c.write(b));
b.flip();
int i;
while ((i = c.read(b)) != -1) {
System.out.println("Read: " + i);
b.clear();
}
Actual results: 实际结果:
Write: 7
写:7
and code crashed... 代码崩溃了...
By why? 为什么? Where is my mistake?
我的错误在哪里?
Thanks. 谢谢。
The flip
method needs to be called before reading data from the buffer. 在从缓冲区读取数据之前 ,需要调用
flip
方法。 The flip()
method, reset the buffer's limit
to the current position and reset the buffer's position
to 0. flip()
方法,将缓冲区的limit
重置为当前位置,并将缓冲区的position
重置为0。
So, if you have 7 byte of data in ByteBuffer
, your position (starting from 0), would be 7. flip()
'ing it, would make limit = 7
, position = 0
. 因此,如果
ByteBuffer
有7个字节的数据,则您的位置(从0开始)为flip()
将其设为limit = 7
, position = 0
。 Now, reading can occur. 现在,可以进行阅读了。
Here's an example on how to best use flip()
: 这是一个关于如何最好地使用
flip()
的示例:
public static final void nioCopy(ReadableByteChannel input, WritableByteChannel output) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
while (input.read(buffer) != -1) {
//Flip buffer
buffer.flip();
//Write to destination
output.write(buffer);
//Compact
buffer.compact();
}
//In case we have remainder
buffer.flip();
while (buffer.hasRemaining()) {
//Write to output
output.write(buffer);
}
}
Despite its (poorly chosen) name, flip()
is not symmetric. 尽管其名称(选择不当),
flip()
还是不对称的。 You must call it before any operation that gets from the buffer (write or get), and call either compact()
or clear()
afterwards to put the buffer back into a state where it is ready for reading or putting. 您必须在从缓冲区进行的任何操作(写入或获取)之前调用它,然后再调用
compact()
或clear()
将缓冲区放回可以读取或放置的状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.