def _write_string_to_file(filename, file_content): """Writes a string to a given file. Args: filename: string, path to a file file_content: string, contents that need to be written to the file Raises: errors.OpError: If there are errors during the operation. """ with GFile(filename, mode="w") as f: f.write(compat.as_text(file_content))
def read(self, filename, binary_mode=False, size=None, continue_from=None): """Reads contents of a file to a string. Args: filename: string, a path binary_mode: bool, read as binary if True, otherwise text size: int, number of bytes or characters to read, otherwise read all the contents of the file (from the continuation marker, if present). continue_from: An opaque value returned from a prior invocation of `read(...)` marking the last read position, so that reading may continue from there. Otherwise read from the beginning. Returns: A tuple of `(data, continuation_token)` where `data' provides either bytes read from the file (if `binary_mode == true`) or the decoded string representation thereof (otherwise), and `continuation_token` is an opaque value that can be passed to the next invocation of `read(...) ' in order to continue from the last read position. """ fs, path = self._fs_path(filename) mode = "rb" if binary_mode else "r" encoding = None if binary_mode else "utf8" if not exists(filename): raise errors.NotFoundError( None, None, "Not Found: " + compat.as_text(filename)) with fs.open(path, mode, encoding=encoding) as f: if continue_from is not None: if not f.seekable(): raise errors.InvalidArgumentError( None, None, "{} is not seekable".format(filename), ) offset = continue_from.get("opaque_offset", None) if offset is not None: f.seek(offset) data = f.read(size) # The new offset may not be `offset + len(data)`, due to decoding # and newline translation. # So, just measure it in whatever terms the underlying stream uses. continuation_token = ({ "opaque_offset": f.tell() } if f.seekable() else {}) return (data, continuation_token)