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 = '<STR_LIT>'<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 C{size} bytes from the file (less if we hit the end of the
file first).  If the C{size} argument is negative or omitted, read all
the remaining data in the file.

@param size: maximum number of bytes to read
@type size: int
@return: data read from the file, or an empty string if EOF was
    encountered immediately
@rtype: str