我有两个流。 NSInputStream
和NSOutputStream
。
现在我想从输入过程中获取一些数据(添加一些帧对它们进行编码等等)并传递给输出。到目前为止一切都很好。
问题是NSOutputStream
API - write:maxLength:
可以返回写入的实际字节数。该值可以与传递的长度不同。这是一个问题,因为它需要创建额外的逻辑来维护某种缓冲区。
我想避免这种情况。我想现在输出流将接受多少字节而不进行缓冲,这样我就可以计算出我应该从输入流中读取多少数据(我将添加一些帧和编码)。
我不想保留额外的缓冲区。
输出流与TCP套接字相关联,输入流可以与任何类型的资源相关联。
答案 0 :(得分:1)
This is the apple implementation问题:
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
switch(eventCode) {
case NSStreamEventHasSpaceAvailable:
{
uint8_t *readBytes = (uint8_t *)[_data mutableBytes];
readBytes += byteIndex; // instance variable to move pointer
int data_len = [_data length];
unsigned int len = ((data_len - byteIndex >= 1024) ?
1024 : (data_len-byteIndex));
uint8_t buf[len];
(void)memcpy(buf, readBytes, len);
len = [stream write:(const uint8_t *)buf maxLength:len];
byteIndex += len;
break;
}
// continued ...
}
}
在此实现中,一次写入1024字节的块。
并提供了一条说明:
对于一次写入多少字节没有确切的指导。 虽然可以将所有数据写入流中 事件,这取决于外部因素,如行为 内核以及设备和套接字特性。最好的方法是 使用一些合理的缓冲区大小,例如512字节,1千字节(如 在上面的例子中),或页面大小(4千字节)。
如上所述,它取决于另一方。不知道是否可以通过调查接收器来解决这个问题。但是,建议一次写入的大小可能会降低某些字节不会被写入的可能性。应该实施这种逻辑。
答案 1 :(得分:0)
你必须缓冲。在进行尝试之前,流无法预测可以写入的内容。但是你可以通过以下方式保持缓冲区尽可能小:(a)尝试一次写入更少的数据,以及(b)仅缓冲先前尝试中未写入的数据。
这种安排的结果是以空间换取速度。将一个字节缓冲区视为简并情况。