Reading an InputStream into a Data object

Raphael picture Raphael · Mar 2, 2017 · Viewed 12.7k times · Source

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?

Answer

Raphael picture Raphael · Mar 2, 2017

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.