'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.'

def Read(self, path, length=None, offset=0, fh=None):

    if self._IsDir(path):
        raise fuse.FuseOSError(errno.EISDIR)
    fd = aff4.FACTORY.Open(self.root.Add(path), token=self.token)
    if all((hasattr(fd, 'Read'), hasattr(fd, 'Seek'), callable(fd.Read), callable(fd.Seek))):
        if (length is None):
            length = fd.Get(fd.Schema.SIZE)
        fd.Seek(offset)
        return fd.Read(length)
    else:
        raise fuse.FuseOSError(errno.EIO)
