protected function _writeStream($data, $options = array())
    {
        if (empty($options['fp'])) {
            $fp = fopen('php://temp/maxmemory:' . self::$memoryLimit, 'r+');
        } else {
            $fp = $options['fp'];
            fseek($fp, 0, SEEK_END);
        }

        if (!is_array($data)) {
            $data = array($data);
        }

        $append_filter = array();
        if (!empty($options['filter'])) {
            foreach ($options['filter'] as $key => $val) {
                $append_filter[] = stream_filter_append($fp, $key, STREAM_FILTER_WRITE, $val);
            }
        }

        if (!empty($options['error'])) {
            set_error_handler(function($errno, $errstr) {
                throw new ErrorException($errstr, $errno);
            });
            $error = null;
        }

        try {
            foreach ($data as $d) {
                if (is_resource($d)) {
                    rewind($d);
                    while (!feof($d)) {
                        fwrite($fp, fread($d, 8192));
                    }
                } elseif (is_string($d)) {
                    $len = strlen($d);
                    $i = 0;
                    while ($i < $len) {
                        fwrite($fp, substr($d, $i, 8192));
                        $i += 8192;
                    }
                }
            }
        } catch (ErrorException $e) {
            $error = $e;
        }

        foreach ($append_filter as $val) {
            stream_filter_remove($val);
        }

        if (!empty($options['error'])) {
            restore_error_handler();
            if ($error) {
                throw $error;
            }
        }

        return $fp;
    }