code: def read(self, size=-1):
          
          chunksize = size < 0 and self.CHUNKSIZE or min(self.CHUNKSIZE, size)
  
          buf = self._rbuf
          buf.seek(0, os.SEEK_END)
          collected = buf.tell()
  
          while 1:
              if size >= 0 and collected >= size:
                  # we have read enough already
                  break
  
              output = self._read_chunk(chunksize)
              if output is None:
                  continue
  
              if not output:
                  # nothing more to read
                  break
  
              collected += len(output)
              buf.write(output)
  
          # get rid of the old buffer
          rc = buf.getvalue()
          buf.seek(0)
          buf.truncate()
  
          if size >= 0:
              # leave the overflow in the buffer
              buf.write(rc[size:])
              return rc[:size]
          return rc
docs: read a number of bytes from the file and return it as a string
  
          .. note:: this method will block if there is no data already available
  
          :param size:
              the maximum number of bytes to read from the file. < 0 means read
              the file to the end
          :type size: int
  
          :returns: a string of the read file contents