code: def read(self, size=None):
      
      if not self._is_open:
        raise IOError('Not opened.')
  
      if self._current_offset < 0:
        raise IOError('Invalid current offset value less than zero.')
  
      # The SleuthKit is not POSIX compliant in its read behavior. Therefore
      # pytsk3 will raise an IOError if the read offset is beyond the data size.
      if self._current_offset >= self._size:
        return b''
  
      if size is None or self._current_offset + size > self._size:
        size = self._size - self._current_offset
  
      if self._tsk_attribute:
        data = self._tsk_file.read_random(
            self._current_offset, size, self._tsk_attribute.info.type,
            self._tsk_attribute.info.id)
      else:
        data = self._tsk_file.read_random(self._current_offset, size)
  
      # It is possible the that returned data size is not the same as the
      # requested data size. At this layer we don't care and this discrepancy
      # should be dealt with on a higher layer if necessary.
      self._current_offset += len(data)
  
      return data
docs: Reads a byte string from the file-like object at the current offset.
  
      The function will read a byte string of the specified size or
      all of the remaining data if no size was specified.
  
      Args:
        size (Optional[int]): number of bytes to read, where None is all
            remaining data.
  
      Returns:
        bytes: data read.
  
      Raises:
        IOError: if the read failed.
        OSError: if the read failed.