我想读取和写入字节和结构化的值类型,异步,而不必担心解码器和字节偏移:是有什么在那里,让我做到这一点?
这是不可能的BinaryReader或BinaryWriter.您可以从底层读取BaseStream,但文档说明如下:
在读取时或使用BinaryReader时使用基础流可能会导致数据丢失和损坏.例如,可能会多次读取相同的字节,可能会跳过字节,或者字符读取可能变得不可预测.
因此,唯一的方法是推出自己的实现.但这样做的好处值得商榷.微软的Marco Greg在博客文章中添加了以下评论我应该为同步方法公开异步包装器吗?:
Jon:BinaryReader/Writer没有XxxAsync方法的原因是这些类型的方法通常只从先前打开的底层流中读取/写入非常少的字节.实际上,数据经常被缓存,从底层源获取数据所需的时间通常很小,以至于不值得异步进行.
值得注意的是,这些类型的某些方法在某些情况下可能会传输更大量的数据(例如ReadString).更进一步,可能会或可能不会添加这些方法的异步版本,但不太可能在不久的将来发生.
通常,如果您正在读取的数据量很大(至少几百或几千字节),或者您是第一次访问资源(例如,从文件中首次读取),则应该只考虑Async IO方法即使您正在读取一个字节,也可能需要旋转磁盘).
这听起来很合理.如果您确实需要解决方案,除了滚动您自己的BinaryReader/ 之外,还有几种解决方法BinaryWriter.您可以在单独的线程中运行它(这可能效率低下),或者如果您愿意更改文件格式或有线协议,则可以使用此模式(伪代码):
//read packet length
await stream.ReadAsync(buffer);
var packetLength=convertToInt(buffer);
//read complete packet asynchronously
await stream.ReadAsync(buffer,packetLength);
//process packet with BinaryReader
using(var br=new BinaryReader(new MemoryStream(buffer))
{
//...
}
Run Code Online (Sandbox Code Playgroud)
请注意,此模式仅在完整缓冲区容易适合内存且性能可能受损时才有用.