docs: def Read(self, path, length=None, offset=0, fh=None):
      """Reads data from a file.
  
      Args:
        path: The path to the file to read.
        length: How many bytes to read.
        offset: Offset in bytes from which reading should start.
        fh: A file handler. Not used.
  
      Returns:
        A string containing the file contents requested.
  
      Raises:
        FuseOSError: If we try and read a directory or if we try and read an
        object that doesn't support reading.
  
      """
      del fh
  
      if self._IsDir(path):
        raise fuse.FuseOSError(errno.EISDIR)
  
      fd = aff4.FACTORY.Open(self.root.Add(path), token=self.token)
  
      # If the object has Read() and Seek() methods, let's use them.
      if all((hasattr(fd, "Read"), hasattr(fd, "Seek"), callable(fd.Read),
              callable(fd.Seek))):
        # By default, read the whole file.
        if length is None:
          length = fd.Get(fd.Schema.SIZE)
  
        fd.Seek(offset)
        return fd.Read(length)
      else:
        # If we don't have Read/Seek methods, we probably can't read this object.
        raise fuse.FuseOSError(errno.EIO)