public function gets(?int $maxLength = null) : string
    {
        if ($this->closed) {
            throw new IoException('The stream is closed.');
        }

        try {
            $data = ErrorCatcher::run(function() use ($maxLength) {
                if ($maxLength === null) {
                    return fgets($this->handle);
                } else {
                    return fgets($this->handle, $maxLength + 1);
                }
            });
        } catch (\ErrorException $e) {
            throw new IoException($e->getMessage(), 0, $e);
        }

        if ($data === false) {
            return '';
        }

        return $data;
    }