# Make InputStream and OutputStream methods safe and Swifty

**URL:** <https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726>\
**Category:** Pitches\
**Tags:** foundation\
**Created:** [April 26, 2019, 11:22am UTC](https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726 "2019-04-26T11:22:22Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![amosavian](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/amosavian/32/2253_2.png) [@amosavian](https://forums.swift.org/u/amosavian)\
**Post date:** [April 26, 2019, 11:22am UTC](https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726/1 "2019-04-26T11:22:22Z")

</div>

Hi,

Currently, We must pass unsafe pointers to `InputStream.read()` and `OutputStream.write()` methods, which is not suitable when calling them from Swift.

Personally I use these convenience methods which wrap them to make `Stream`s accessible in Swift.

```swift
extension InputStream {
    func readData(maxLength length: Int) throws -> Data {
        var buffer = [UInt8](repeating: 0, count: length)
        let result = self.read(&buffer, maxLength: buffer.count)
        if result < 0 {
            throw self.streamError ?? POSIXError(.EIO)
        } else {
            return Data(buffer.prefix(result))
        }
    }
}

extension OutputStream {
    func write<DataType: DataProtocol>(_ data: DataType) throws -> Int {
        var buffer = Array(data)
        let result = self.write(&buffer, maxLength: buffer.count)
        if result < 0 {
            throw self.streamError ?? POSIXError(.EIO)
        } else {
            return result
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![Tony\_Parker](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tony_parker/32/273_2.png) [@Tony\_Parker](https://forums.swift.org/u/Tony_Parker)\
**Post date:** [April 30, 2019, 5:05pm UTC](https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726/2 "2019-04-30T17:05:35Z")

</div>

I think there are a couple of challenges with `InputStream` API. One is clearly this, which I think actually could use some of the newer `Data` methods we've added (@itaiferber?). Also, these are inherently tied to run loop, which can surprise people.

Another challenge is that `InputStream` and `OutputStream` are class cluster types, and have those unsafe pointer APIs as their base functionality for subclasses to implement. I don't think we have a great way to fix those without deprecating the entire class hierarchy. `Formatter` has a similar problem since it's required function is an error `String` instead of `Error` (it predates `NSError`).

---

<div class="post-metadata">

**Author:** ![amosavian](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/amosavian/32/2253_2.png) [@amosavian](https://forums.swift.org/u/amosavian)\
**Post date:** [April 30, 2019, 7:43pm UTC](https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726/3 "2019-04-30T19:43:20Z")

</div>

> [@Tony\_Parker](#):
>
> actually could use some of the newer `Data` methods we've added

Indeed I intended to just show a demo. Of course it is open for optimization.

> [@Tony\_Parker](#):
>
> Another challenge is that `InputStream` and `OutputStream` are class cluster types, and have those unsafe pointer APIs as their base functionality for subclasses to implement.

Thus in this case we should declare these helper functions as `final`?

byte buffers are easy to deal with in C, but a little odd in Swift. I only propose to make Swift codes much more readable when dealing with these two frequently used methods of `Stream` class.

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [March 26, 2020, 4:00pm UTC](https://forums.swift.org/t/make-inputstream-and-outputstream-methods-safe-and-swifty/23726/4 "2020-03-26T16:00:03Z")

</div>

I find myself needing this right now. Did anything come of it? Might make sense as a `Data` initializer:

```
let data = Data(from: stream)

```
