将 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 == trueread == 0 的语义是什么;对我来说听起来像是一个错误场景。 @Raphael InputStream.read(_ buffer: UnsafeMutablePointer&lt;UInt8&gt;, maxLength len: Int) -&gt; Int 如果有错误则返回 -1,如果没有要读取的内容,则返回 0,如果还有要读取的字节,则返回 &gt;1 如果必须执行读取以实际检查字节是否可用,则 hasBytesAvailable 允许返回 true(请阅读 NSInputStream 文档)。正确的实现必须检查读取的结果代码。我用正确的错误处理修改了接受的答案。

以上是关于将 InputStream 读入 Data 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Kotlin 中,如何将 InputStream 的全部内容读入字符串?

如何在 Java 中将字符串读入 inputStream? [复制]

是否可以将 Process stdout InputStream 读入 NIO ByteBuffer?

流操作

java里面InputStream类型转换成String类型怎么实现

如何从 JsonObject 创建 InputStream 对象