读取和写入 Cloud Storage

本文档介绍了如何使用适用于 Cloud Storage 的 App Engine 客户端库在 App Engine 应用中使用 Cloud Datastore 存储和检索数据,它假定您已完成设置 Cloud Storage 中所列的任务,且已激活 Cloud Storage 存储分区并下载了客户端库。本文档还假定您已阅读 Python 2 App Engine 标准环境快速入门所述内容,了解如何构建 App Engine 应用。

必要的导入

main.py 文件包含使用客户端库访问 Cloud Storage 的典型导入项:

import logging
import os
import cloudstorage as gcs
import webapp2

from google.appengine.api import app_identity

您需要 os 模块和 app_identity API 才能在运行时获取默认存储分区名称。请注意,如果您不使用默认存储分区,则需要通过其他方法提供存储分区名称。

指定 Cloud Storage 存储分区

在 Cloud Storage 中执行任何操作之前,您需要提供存储分区名称。最简单的方法是使用项目的默认存储分区(可以按如下方式获取):

def get(self):
  bucket_name = os.environ.get('BUCKET_NAME',
                               app_identity.get_default_gcs_bucket_name())

  self.response.headers['Content-Type'] = 'text/plain'
  self.response.write('Demo GCS Application running from Version: '
                      + os.environ['CURRENT_VERSION_ID'] + '\n')
  self.response.write('Using bucket name: ' + bucket_name + '\n\n')

您必须先为项目创建默认存储分区,对 get_default_gcs_bucket_name 的调用才会成功。

写入 Cloud Storage

以下示例介绍如何写入存储分区:

def create_file(self, filename):
  """Create a file.

  The retry_params specified in the open call will override the default
  retry params for this particular file handle.

  Args:
    filename: filename.
  """
  self.response.write('Creating file %s\n' % filename)

  write_retry_params = gcs.RetryParams(backoff_factor=1.1)
  gcs_file = gcs.open(filename,
                      'w',
                      content_type='text/plain',
                      options={'x-goog-meta-foo': 'foo',
                               'x-goog-meta-bar': 'bar'},
                      retry_params=write_retry_params)
  gcs_file.write('abcde\n')
  gcs_file.write('f'*1024*4 + '\n')
  gcs_file.close()
  self.tmp_filenames_to_clean_up.append(filename)

请注意,在打开文件进行写入的调用中,该示例会指定特定 Cloud Storage 标头来写入该文件的自定义元数据;可以使用 cloudstorage.stat() 检索此元数据。您可以在 cloudstorage.open() 参考文档中找到受支持的标头列表。

另请注意,未设置 x-goog-acl 标头。这意味着,公共读取的默认 Cloud Storage ACL 将在写入存储分区时应用于该对象。

最后,请注意在完成写入后,通过调用关闭文件。否则,不会将该文件写入 Cloud Storage。请注意,调用 Python 文件函数 close() 后,您无法再对文件执行附加操作。如果您需要修改文件,则必须调用 Python 文件函数 open() 以在写入模式下再次打开该文件,但这执行的是改写操作而不是附加操作。

从 Cloud Storage 读取

以下示例演示了如何从存储分区读取完整文件:

def read_file(self, filename):
  self.response.write('Reading the full file contents:\n')

  gcs_file = gcs.open(filename)
  contents = gcs_file.read()
  gcs_file.close()
  self.response.write(contents)

如需从文件中读取选定的行,请使用 seek()

def read_partial_file(self, filename):
  self.response.write('Abbreviated file content (first line and last 1K):\n')

  gcs_file = gcs.open(filename)
  self.response.write(gcs_file.readline())
  gcs_file.seek(-1024, os.SEEK_END)
  self.response.write(gcs_file.read())
  gcs_file.close()

在这两个示例中,您传递给 cloudstorage.open()filename 参数是 YOUR_BUCKET_NAME/PATH_IN_GCS 格式的文件路径。请注意,cloudstorage.open() 的默认值是只读模式。打开文件进行读取时,您无需指定模式。

列出存储分区内容

该示例代码演示了如何使用 markermax_keys 参数浏览包含大量文件的存储分区,即浏览存储分区的内容列表:

def list_bucket(self, bucket):
  """Create several files and paginate through them.

  Production apps should set page_size to a practical value.

  Args:
    bucket: bucket.
  """
  self.response.write('Listbucket result:\n')

  page_size = 1
  stats = gcs.listbucket(bucket + '/foo', max_keys=page_size)
  while True:
    count = 0
    for stat in stats:
      count += 1
      self.response.write(repr(stat))
      self.response.write('\n')

    if count != page_size or count == 0:
      break
    stats = gcs.listbucket(bucket + '/foo', max_keys=page_size,
                           marker=stat.filename)

请注意,完整的文件名显示为一个不含目录分隔符的字符串。如果要显示该文件,让其目录层次结构更易识别,请将 delimiter 参数设置为要使用的目录分隔符。

删除 Cloud Storage 中的文件

以下代码演示了如何使用 cloudstorage.delete() 方法(以 gcs 形式导入)删除 Cloud Storage 中的文件。

def delete_files(self):
  self.response.write('Deleting files...\n')
  for filename in self.tmp_filenames_to_clean_up:
    self.response.write('Deleting file %s\n' % filename)
    try:
      gcs.delete(filename)
    except gcs.NotFoundError:
      pass

此示例演示了如何清理在向 Cloud Storage 中写入数据部分中写入存储分区的文件。

后续步骤