如何解决使用OutputStream在Swift中的文件中写入CircularBufferswift-nio吗?
我正在尝试使用SwiftNIO中的CircularBuffer<UInt8>
存储数据,一旦缓冲区快满了,就使用OutputStream
将内容转储到文件中。不幸的是,OutputStream.write()
方法使用UnsafePointer
作为参数,而CircularBuffer
可以输出UnsafeBufferPointer
。是否可以将CircularBuffer
转换为UnsafePointer
?
我已经尝试使用以下代码扩展CircularBuffer,并将其成功地用于将结构转换为字节数组,因为有人建议CircularBuffer实际上是一个结构,但是我的输出文件中出现了垃圾:
extension CircularBuffer {
func toBytes() -> [UInt8] {
let capacity = MemoryLayout<Self>.size
var mutableValue = self
return withUnsafePointer(to: &mutableValue) {
return $0.withMemoryRebound(to: UInt8.self,capacity: capacity) {
return Array(UnsafeBufferPointer(start: $0,count: capacity))
}
}
}
}
有什么想法吗?
解决方法
CircularBuffer
是具有内部ContiguousArray
用于元素存储的结构。 ContiguousArray
也是一个结构,带有指向实际元素存储的内部指针。
您当前的代码会产生垃圾,因为它返回struct CircularBuffer
本身的内存表示形式,而不是它表示的元素的字节。
作为集合,CircularBuffer
有一个withContiguousStorageIfAvailable()
方法,如果存在这种连续存储,它会使用指向元素存储的指针来调用闭包。 UnsafeBufferPointer
个自变量,您可以从中获取baseAddress
:
var buffer: CircularBuffer<UInt8> = ...
let os: OutputStream = ...
// ...
let amountWritten = buffer.withContiguousStorageIfAvailable {
os.write($0.baseAddress!,maxLength: $0.count)
}
但是有一个问题:CircularBuffer
仅继承了Sequence
的默认实现,该默认实现返回nil
而不调用闭包。这是known issue。因此上面的代码可以编译,但是不起作用。
一种简单的方法(以复制内容为代价)是使用可以从集合中初始化数组的方法:
var buffer: CircularBuffer<UInt8> = ...
let os: OutputStream = ...
// ...
let contents = Array(buffer)
let amountWritten = os.write(contents,maxLength: contents.count)
,
您也可以一次循环浏览缓冲区的各个元素,尽管这可能效率很低:
var cb = CircularBuffer<UInt8>()
cb.append(contentsOf:[1,2,3])
cb.append(contentsOf:[4,5,6])
let stream = OutputStream.toMemory()
stream.open()
for var i in cb {
stream.write(&i,maxLength:1)
print(i)
}
stream.close()
print(stream.property(forKey: .dataWrittenToMemoryStreamKey) as Any)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。