def read(self, size=None):
if self._closed:<EOL><INDENT>raise IOError("<STR_LIT>")<EOL><DEDENT>if not (self._flags & self.FLAG_READ):<EOL><INDENT>raise IOError("<STR_LIT>")<EOL><DEDENT>if (size is None) or (size < <NUM_LIT:0>):<EOL><INDENT>result = self._rbuffer<EOL>self._rbuffer = bytes()<EOL>self._pos += len(result)<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>new_data = self._read(self._DEFAULT_BUFSIZE)<EOL><DEDENT>except EOFError:<EOL><INDENT>new_data = None<EOL><DEDENT>if (new_data is None) or (len(new_data) == <NUM_LIT:0>):<EOL><INDENT>break<EOL><DEDENT>result += new_data<EOL>self._realpos += len(new_data)<EOL>self._pos += len(new_data)<EOL><DEDENT>return result<EOL><DEDENT>if size <= len(self._rbuffer):<EOL><INDENT>result = self._rbuffer[:size]<EOL>self._rbuffer = self._rbuffer[size:]<EOL>self._pos += len(result)<EOL>return result<EOL><DEDENT>while len(self._rbuffer) < size:<EOL><INDENT>read_size = size - len(self._rbuffer)<EOL>if self._flags & self.FLAG_BUFFERED:<EOL><INDENT>read_size = max(self._bufsize, read_size)<EOL><DEDENT>try:<EOL><INDENT>new_data = self._read(read_size)<EOL><DEDENT>except EOFError:<EOL><INDENT>new_data = None<EOL><DEDENT>if (new_data is None) or (len(new_data) == <NUM_LIT:0>):<EOL><INDENT>break<EOL><DEDENT>self._rbuffer += new_data<EOL>self._realpos += len(new_data)<EOL><DEDENT>result = self._rbuffer[:size]<EOL>self._rbuffer = self._rbuffer[size:]<EOL>self._pos += len(result)<EOL>return result<EOL>
Read at most ``size`` bytes from the file (less if we hit the end of
the file first).  If the ``size`` argument is negative or omitted,
read all the remaining data in the file.

.. note::
    ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in
    ``self._flags``), because SSH treats all files as binary, since we
    have no idea what encoding the file is in, or even if the file is
    text data.

:param int size: maximum number of bytes to read
:returns:
    data read from the file (as bytes), or an empty string if EOF was
    encountered immediately