将数据作为原始数据读取和写入流?
Posted
技术标签:
【中文标题】将数据作为原始数据读取和写入流?【英文标题】:reading and writing data to streams as raw data? 【发布时间】:2012-06-23 19:21:18 【问题描述】:我通过外部附件框架打开了以下输入和输出流:
session = [[EASession alloc] initWithAccessory:acc forProtocol:protocol];
if (session)
[[session inputStream] setDelegate:self];
[[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session inputStream] open];
[[session outputStream] setDelegate:self];
[[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[session outputStream] open];
现在我有一个非常愚蠢的问题,就像我的大多数新手问题一样。如何将原始的 1 字节数据发送到流中?说,我想发送 0x06。我该怎么做?
然后...如何从流中读取数据?我将被发送回数据以逐字节处理......字节将是字节范围(0x00 - 0xFF)内的数字。
感谢您的耐心和帮助!
【问题讨论】:
【参考方案1】:逐字节写入数据不是最有效的方式,但如果你坚持:
uint8_t aByte = 0x06;
if ([[session outputStream] write:&aByte maxLength:1] < 0)
/* handle error */;
同样,逐字节读取:
uint8_t aByte;
NSInteger result = [[session inputStream] read:&aByte maxLength:1];
if (result > 0)
/* handle received byte */;
else if (result == 0)
/* handle end-of-stream */;
else
/* handle error */;
如果要读取或写入更大的数据块,请将指针传递给大于一字节的缓冲区并指定长度。一定要处理短读和写,返回码是正数但小于你指定的。您需要等待流准备好更多内容并从中断处继续。对于阅读,您还可以使用-getBuffer:length:
,其中框架会分配一个长度由其选择的缓冲区。
【讨论】:
另一个愚蠢的问题:如何将 aByte 打印到 NSLog?当我执行 NSLog(@"%@", aByte) 或 NSLog(@"%s", aByte)...程序崩溃。 “%@”格式说明符将相应的参数视为对象指针。 "%s" 将其视为不可预知编码的 C 字符串指针。崩溃是因为aByte
不是任何类型的有效指针,因此取消引用它会访问无效地址。对于aByte
,您可以使用“%hhu”(十进制)或“%hhx”(十六进制)。 “u”和“x”表示无符号整数类型。一个“h”表示“short int”,而“hh”表示“char”(这是uint8_t
类型的基础)。以上是关于将数据作为原始数据读取和写入流?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 BluetoothChat 的输入/输出流中读取/写入原始十六进制字节?
读取 Amazon Kinesis Firehose 流写入 s3 的数据