将 InputStream 读入 Data 对象
Posted
技术标签:
【中文标题】将 InputStream 读入 Data 对象【英文标题】:Reading an InputStream into a Data object 【发布时间】:2017-07-22 12:13:30 【问题描述】:在 Swift 3.x 中,我们通常使用Data
处理二进制数据;从中您可以生成大多数其他重要的类型,并且上面还有有用的功能。
但是如何从InputStream
创建一个Data
?有什么好办法吗?
【问题讨论】:
【参考方案1】:我找不到好的方法。我们可以围绕不安全的东西创建一个漂亮的包装器:
extension Data
init(reading input: InputStream) throws
self.init()
input.open()
defer
input.close()
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
defer
buffer.deallocate()
while input.hasBytesAvailable
let read = input.read(buffer, maxLength: bufferSize)
if read < 0
//Stream error occured
throw input.streamError!
else if read == 0
//EOF
break
self.append(buffer, count: read)
这是针对 Swift 5 的。使用测试查找完整代码(以及仅读取部分流的变体)here。
【讨论】:
善用 defer 语句。【参考方案2】:以上代码,可以无限循环。 当我将 httpbodyInpustream 转换为数据时,它发生了。 所以我添加了一个条件。
extension Data
init(reading input: InputStream)
self.init()
input.open()
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
while input.hasBytesAvailable
let read = input.read(buffer, maxLength: bufferSize)
if (read == 0)
break // added
self.append(buffer, count: read)
buffer.deallocate(capacity: bufferSize)
input.close()
【讨论】:
听起来流坏了;hasBytesAvailable
应该返回 false
,不是吗?不确定hasBytesAvailable == true
但read == 0
的语义是什么;对我来说听起来像是一个错误场景。
@Raphael InputStream.read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) -> Int
如果有错误则返回 -1
,如果没有要读取的内容,则返回 0
,如果还有要读取的字节,则返回 >1
。
如果必须执行读取以实际检查字节是否可用,则 hasBytesAvailable 允许返回 true(请阅读 NSInputStream 文档)。正确的实现必须检查读取的结果代码。我用正确的错误处理修改了接受的答案。以上是关于将 InputStream 读入 Data 对象的主要内容,如果未能解决你的问题,请参考以下文章
在 Kotlin 中,如何将 InputStream 的全部内容读入字符串?
如何在 Java 中将字符串读入 inputStream? [复制]
是否可以将 Process stdout InputStream 读入 NIO ByteBuffer?