从 ByteBuffer 获取到 byte[] 不写入到 byte[]
Posted
技术标签:
【中文标题】从 ByteBuffer 获取到 byte[] 不写入到 byte[]【英文标题】:Get from ByteBuffer to byte[] does not write to byte[] 【发布时间】:2012-03-22 09:53:38 【问题描述】:我从 SocketChannel 连续读取 BLOCKSIZE(例如 512)字节块到 ByteBuffer 中。然后,我想将 ByteBuffer 内容附加到 byte[] 并进行下一轮。结果将是一个 byte[],其中包含从 SocketChannel 读取的所有字节。
现在,System.arraycopy(...) 按预期工作。但是当我使用 ByteBuffer 的 get(result, offset, length) 时,什么都没有写入。结果数组值保持为零。
为什么会这样?
public final static int BLOCKSIZE = 512;
public byte[] getReceivedData()
int offset = 0, read;
byte[] result = ;
ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE);
try
while (true)
read = _socketChannel.read(buffer);
if (read < 1)
// Nothing was read.
break;
// Enlarge result so we can append the bytes we just read.
result = Arrays.copyOf(result, result.length + read);
// This works as expected.
System.arraycopy(buffer.array(), 0, result, offset * BLOCKSIZE, read);
// With this, however, nothing is written to result. Why?
buffer.get(result, offset * BLOCKSIZE, read);
if (read < BLOCKSIZE)
// Nothing left to read from _socketChannel.
break;
buffer.clear();
catch (IOException e)
e.printStackTrace();
return result;
编辑:
我注意到offset++
也不见了。因此,如果通道上的字节数超过BLOCKSIZE
,事情就会变得一团糟......
无论如何,ByteArrayOutputStream
确实让事情变得更简单,所以我决定使用它。
工作代码:
public byte[] getReceivedData()
int read;
ByteArrayOutputStream result = new ByteArrayOutputStream();
ByteBuffer buffer = ByteBuffer.allocate(BLOCKSIZE);
try
while (true)
buffer.clear();
read = _socketChannel.read(buffer);
if (read < 1)
break;
result.write(buffer.array(), 0, read);
if (read < BLOCKSIZE)
break;
catch (IOException e)
e.printStackTrace();
return result.toByteArray();
【问题讨论】:
【参考方案1】:你需要flip()
get()
之前的缓冲区,然后compact()
它。
如果read == -1
,你不仅需要跳出循环,还要关闭通道。
【讨论】:
flip()
成功了,谢谢。我认为compact()
不是必需的。在 get()
ing 缓冲区中的所有内容之后,没有任何东西可以压缩,而且每次迭代都是 clear()
ed。另外,感谢您关闭频道的提示。我知道渠道保持开放,这是有意的。客户可以随时发送新数据。
@riha 错了。在您获得 -1 后,没有客户会再向您发送任何数据。那是通道上的流结束,这意味着对等方已关闭连接,或者至少将其关闭以进行输出。关闭它。
嗯好吧,那它也确实应该在我这边关闭。虽然这在我的情况下永远不应该发生,但那是另一回事了。再次感谢。【参考方案2】:
您的结果数组的长度为 0,不能保存任何信息。字节数组不会增长,并且您无法附加缓冲区的内容。使用 java.io.ByteArrayOutputStream 累加结果。
【讨论】:
错了。他的结果数组在循环内重新分配。ByteArrayOutputStream
的好提示。这让事情变得更简单了。以上是关于从 ByteBuffer 获取到 byte[] 不写入到 byte[]的主要内容,如果未能解决你的问题,请参考以下文章