Search code examples
swiftstreaminputstreambinary-data

Reading an InputStream into a Data object


In Swift 3.x, we usually handle binary data using Data; from it you can generate most other important types, and there are useful functions on it.

But how do I create a Data from an InputStream? Is there a nice way?


Solution

  • I could not find a nice way. We can create a nice-ish wrapper around the unsafe stuff:

    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)
            }
        }
    }
    

    This is for Swift 5. Find full code with test (and a variant that reads only some of the stream) here.