使用python操作google cloud storage最直接的方式是通过官方google-cloud-storage库,首先安装该库:pip install google-cloud-storage;1. 认证可通过设置google_application_credentials环境变量指向服务账号密钥文件,或在gcp环境中自动认证;2. 创建storage.client实例后即可操作桶和对象;3. 上传文件使用blob.upload_from_filename(),支持大文件的可恢复上传;4. 下载文件可用blob.download_to_filename()或流式下载避免内存溢出;5. 列出文件时使用client.list_blobs()并配合prefix和delimiter提升效率;6. 删除文件调用blob.delete();7. 权限管理推荐使用iam,临时访问可通过blob.generate_signed_url()生成签名url;8. 元数据可设置自定义键值对并通过blob.patch()更新;9. 错误处理需捕获google.api_core.exceptions如notfound、forbidden等;10. 性能优化包括并发删除、分页筛选和避免n+1 api调用。完整操作流程简洁高效,适用于各类生产场景。

Python操作Google Cloud Storage,最直接且推荐的方式就是使用官方提供的
google-cloud-storage
要使用Python操作Google Cloud Storage,首先需要安装官方客户端库。这通常通过pip完成:
pip install google-cloud-storage
安装完成后,核心就是创建
storage.Client
立即学习“Python免费学习笔记(深入)”;
GOOGLE_APPLICATION_CREDENTIALS
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/key.json"
一旦认证就绪,操作就变得非常直观了。
基本操作示例:
from google.cloud import storage
import os
# 假设已通过 GOOGLE_APPLICATION_CREDENTIALS 环境变量进行认证
# 或者在GCP环境中运行,会自动认证
client = storage.Client()
# 替换为你的桶名称
bucket_name = "your-unique-bucket-name"
bucket = client.bucket(bucket_name)
# --- 上传文件 ---
local_file_path = "path/to/your/local_file.txt" # 确保这个文件存在
destination_blob_name = "my_uploaded_file.txt" # 在GCS中存储的名称
try:
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(local_file_path)
print(f"文件 {local_file_path} 已成功上传到 {bucket_name}/{destination_blob_name}")
# 也可以从字符串上传
blob_from_string = bucket.blob("string_content_file.txt")
blob_from_string.upload_from_string("这是一段从Python字符串上传到GCS的内容。")
print("字符串内容已上传。")
except Exception as e:
print(f"上传文件时发生错误: {e}")
# --- 下载文件 ---
download_destination_path = "downloaded_file.txt"
try:
blob = bucket.blob(destination_blob_name)
blob.download_to_filename(download_destination_path)
print(f"文件 {bucket_name}/{destination_blob_name} 已成功下载到 {download_destination_path}")
# 也可以下载为字符串或字节
downloaded_content_bytes = blob.download_as_bytes()
print(f"下载的字节内容前20字符: {downloaded_content_bytes[:20].decode('utf-8')}")
downloaded_content_string = blob.download_as_string().decode('utf-8')
print(f"下载的字符串内容前20字符: {downloaded_content_string[:20]}")
except Exception as e:
print(f"下载文件时发生错误: {e}")
# --- 列出桶中的所有文件(对象/Blob)---
print(f"\n列出桶 {bucket_name} 中的所有文件:")
try:
blobs = client.list_blobs(bucket_name)
for blob in blobs:
print(f"- {blob.name} (大小: {blob.size} 字节, 创建时间: {blob.time_created})")
except Exception as e:
print(f"列出文件时发生错误: {e}")
# --- 删除文件 ---
file_to_delete = "string_content_file.txt" # 替换为你要删除的文件名
try:
blob = bucket.blob(file_to_delete)
blob.delete()
print(f"文件 {file_to_delete} 已成功从 {bucket_name} 删除。")
except Exception as e:
print(f"删除文件 {file_to_delete} 时发生错误: {e}")
说实话,刚开始接触时,认证和项目ID这些概念可能会觉得有点绕,但一旦配置好了,后面的文件操作就非常顺畅,API设计得相当直观。
处理大文件是云存储场景下非常常见的需求,也是一个性能与稳定性上的挑战。Python的
google-cloud-storage
对于大文件上传,当你使用
blob.upload_from_filename()
chunk_size
from google.cloud import storage
client = storage.Client()
bucket = client.bucket("your-large-file-bucket")
large_local_file = "path/to/your/large_file.zip"
destination_blob_name = "large_archive.zip"
blob = bucket.blob(destination_blob_name)
# upload_from_filename 默认支持可恢复上传
# 也可以显式指定 chunk_size,例如 1MB (1024 * 1024 字节)
# blob.chunk_size = 1024 * 1024
try:
blob.upload_from_filename(large_local_file)
print(f"大文件 {large_local_file} 已成功上传到 {bucket.name}/{destination_blob_name}")
except Exception as e:
print(f"上传大文件时发生错误: {e}")而对于大文件下载,同样也有几种策略。
blob.download_to_filename()
import io
from google.cloud import storage
client = storage.Client()
bucket = client.bucket("your-large-file-bucket")
large_blob_name = "large_archive.zip" # 假设这个大文件已存在
# 下载到本地文件
download_path = "downloaded_large_archive.zip"
blob = bucket.blob(large_blob_name)
try:
blob.download_to_filename(download_path)
print(f"大文件 {large_blob_name} 已下载到 {download_path}")
except Exception as e:
print(f"下载大文件时发生错误: {e}")
# 流式下载(如果需要边读边处理,不一次性加载到内存)
# 这通常用于非常大的文件,或需要即时处理数据流的场景
try:
# 创建一个可写入的内存文件对象
# 或者直接传递一个打开的文件句柄
buffer = io.BytesIO()
blob.download_to_file(buffer)
buffer.seek(0) # 将指针移到开头
# 现在你可以从 buffer 中读取数据了
print(f"通过流式下载,读取到 {len(buffer.getvalue())} 字节。")
# 例如:处理前100字节
# print(buffer.read(100))
except Exception as e:
print(f"流式下载大文件时发生错误: {e}")
在处理超大文件时,除了客户端库的自动处理,我们还要考虑到自身的网络带宽和GCS的吞吐量限制。如果文件真的非常非常大(比如几百GB甚至TB),可能还需要配合GCS的并行复合上传(Parallel Composite Uploads)策略,但这通常需要更底层的API操作或特定的工具。好在对于大多数日常应用,客户端库的默认行为已经足够高效。
在GCS中,文件的权限控制和元数据管理是其强大功能的一部分,允许你精细地控制谁可以访问什么,以及为文件附加额外信息。Python客户端库提供了直观的接口来处理这些。
权限管理:
GCS主要通过两种方式管理权限:
虽然推荐使用IAM在桶级别管理,但在某些特定场景下,你可能需要对单个对象进行更细粒度的控制,例如生成一个临时访问链接。
生成签名URL(Signed URLs): 这是一种非常强大的功能,允许你在不公开文件的情况下,为特定用户或服务生成一个有时效性的URL,让他们可以上传或下载文件。这在分享临时文件或授权第三方上传内容时非常有用。
from google.cloud import storage
from datetime import timedelta
client = storage.Client()
bucket = client.bucket("your-bucket-name")
blob_name = "private_document.pdf"
blob = bucket.blob(blob_name)
# 生成一个可读的签名URL,有效期1小时
signed_url_read = blob.generate_signed_url(
version="v4",
expiration=timedelta(hours=1),
method="GET" # 允许GET请求,即下载
)
print(f"\n生成的可读签名URL (1小时有效): {signed_url_read}")
# 生成一个可写入的签名URL,有效期30分钟
signed_url_write = blob.generate_signed_url(
version="v4",
expiration=timedelta(minutes=30),
method="PUT", # 允许PUT请求,即上传
content_type="application/pdf" # 上传时必须匹配此Content-Type
)
print(f"生成的可写签名URL (30分钟有效): {signed_url_write}")元数据管理:
每个GCS对象都可以关联一组元数据。这些元数据分为两种:
Content-Type
Cache-Control
Content-Encoding
Size
CRC32C
from google.cloud import storage
client = storage.Client()
bucket = client.bucket("your-bucket-name")
blob_name = "my_image.jpg"
blob = bucket.blob(blob_name)
# 假设文件已存在,或者先上传一个文件
# blob.upload_from_filename("path/to/my_image.jpg")
# 获取并打印当前元数据
blob.reload() # 确保获取到最新的元数据
print(f"\n文件 {blob_name} 的当前元数据: {blob.metadata}")
print(f"Content-Type: {blob.content_type}")
# 设置或更新元数据
# 注意:修改元数据会触发一个对象更新操作
new_metadata = {
"project_id": "xyz123",
"processed_status": "pending",
"original_source": "mobile_upload"
}
blob.metadata = new_metadata
blob.patch() # 将更改应用到GCS
print(f"更新后的元数据: {blob.metadata}")
# 也可以直接设置 Content-Type 等系统元数据
blob.content_type = "image/jpeg"
blob.cache_control = "public, max-age=3600"
blob.patch()
print(f"更新Content-Type和Cache-Control后的元数据: {blob.content_type}, {blob.cache_control}")
# 删除某个自定义元数据键
if blob.metadata and "processed_status" in blob.metadata:
del blob.metadata["processed_status"]
blob.patch()
print(f"删除 'processed_status' 后的元数据: {blob.metadata}")
自定义元数据在构建复杂的数据处理管道或内容管理系统时非常有用,它们允许你为存储在GCS中的数据附加业务逻辑相关的上下文信息,而无需修改文件内容本身。
在实际生产环境中,仅仅实现功能是不够的,还需要考虑代码的健壮性和效率。Python操作GCS时,错误处理和性能优化是两个不能忽视的方面。
错误处理:
网络抖动、权限配置失误、资源不存在等都是云服务操作中常客。
google-cloud-storage
google.api_core.exceptions
常见的异常类型:
NotFound
Forbidden
BadRequest
Conflict
InternalServerError
ServiceUnavailable
from google.cloud import storage
from google.api_core import exceptions
client = storage.Client()
bucket_name = "non-existent-bucket-12345" # 故意使用一个不存在的桶
blob_name = "test_file.txt"
try:
bucket = client.get_bucket(bucket_name)
print(f"桶 {bucket_name} 存在。")
except exceptions.NotFound:
print(f"错误:桶 {bucket_name} 不存在。")
except exceptions.Forbidden:
print(f"错误:没有权限访问桶 {bucket_name}。")
except Exception as e:
print(f"获取桶时发生未知错误: {e}")
# 尝试上传一个文件到不存在的桶,会触发 NotFound 异常
try:
bucket = client.bucket(bucket_name) # 客户端对象不会立即检查桶是否存在
blob = bucket.blob(blob_name)
blob.upload_from_string("Some content.")
print(f"文件 {blob_name} 已上传。")
except exceptions.NotFound:
print(f"上传失败:目标桶 {bucket_name} 不存在。")
except exceptions.Forbidden:
print(f"上传失败:没有权限向桶 {bucket_name} 写入。")
except Exception as e:
print(f"上传文件时发生未知错误: {e}")
在实际应用中,你可能还需要实现重试逻辑,特别是对于瞬时错误(如
ServiceUnavailable
InternalServerError
性能考量:
批量操作: 如果你需要对桶中的大量文件进行相同操作(例如,删除多个文件),尽量使用客户端库提供的批量操作方法,而不是循环逐个处理。虽然GCS客户端库没有直接的
batch_delete_blobs
asyncio
# 假设要删除多个文件
# from concurrent.futures import ThreadPoolExecutor
#
# files_to_delete = ["file1.txt", "file2.txt", "file3.txt"]
#
# def delete_single_blob(blob_name):
# try:
# bucket.blob(blob_name).delete()
# print(f"已删除 {blob_name}")
# except Exception as e:
# print(f"删除 {blob_name} 失败: {e}")
#
# with ThreadPoolExecutor(max_workers=5) as executor:
# executor.map(delete_single_blob, files_to_delete)分页与筛选: 列出桶中文件时,如果文件数量巨大,不要一次性加载所有文件。
client.list_blobs()
prefix
delimiter
# 列出特定前缀的文件
print("\n列出 'images/' 目录下的文件:")
blobs = client.list_blobs(bucket_name, prefix="images/")
for blob in blobs:
print(f"- {blob.name}")
# 列出桶根目录下的“文件夹”(通过delimiter)
print("\n列出桶根目录下的“文件夹”:")
blobs = client.list_blobs(bucket_name, delimiter="/")
for blob in blobs:
if blob.name.endswith('/'): # 这是一个目录
print(f"- {blob.name} (目录)")
else:
print(f"- {blob.name} (文件)")避免N+1问题: 如果你需要获取大量文件的元数据,尽量在
list_blobs
fields
blob.reload()
以上就是Python怎样操作Google Cloud Storage?客户端库的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号