本页面讨论 Cloud Storage 中的文件夹,以及这些文件夹在 Cloud Storage 工具之间有何不同。
概览
Cloud Storage 使用平面命名空间运行,这意味着文件夹实际上不会存在于 Cloud Storage 中。如果您在存储桶 your-bucket
中创建名为 folder1/file.txt
的对象,则该对象的路径为 your-bucket/folder1/file.txt
,但没有名为 folder1
的文件夹;字符串 folder1
是对象名称的一部分。
但是,Cloud 控制台和 gsutil 可以提供分层文件树的幻觉:
Cloud 控制台会以类似于本地文件浏览器的文件夹创建可视化的表示形式。
gsutil 使用各种规则模拟典型的命令行目录体验。
工具
点击下面的标签,了解各个工具如何处理文件夹。
控制台
在 Cloud Console 中,您可以在存储分区中创建一个空文件夹,或上传现有文件夹。
当您上传现有文件夹时,该文件夹的名称将成为文件夹中所有对象的路径的一部分。所有子文件夹及其包含的对象也会包含在上传内容中。
要创建文件夹,请执行以下操作:
- 在 Google Cloud Console 中,转到 Cloud Storage 浏览器页面。
导航到存储分区。
点击创建文件夹以创建空的新文件夹,或点击上传文件夹来上传现有文件夹。
gsutil
为了实现错开分层文件树的视觉效果,gsutil 会应用以下规则来确定应将命令中的目标网址视为对象名称还是文件夹:
如果目标网址以
/
字符结尾,则 gsutil 会将目标网址视为文件夹。例如,假设存在以下命令,其中your-file
是文件的名称:gsutil cp your-file gs://your-bucket/abc/
其结果为,gsutil 会创建一个名为
gs://your-bucket/abc/your-file
的对象。如果您将多个源文件复制到目标网址,则 gsutil 会将目标网址视为文件夹。例如,假设存在以下命令,其中
your-dir
是包含file1
和file2
等文件的文件夹:gsutil cp -r your-dir gs://your-bucket/abc
其结果为,gsutil 会创建对象
gs://your-bucket/abc/your-dir/file1
和gs://your-bucket/abc/your-dir/file2
。如果上述规则均不适用,gsutil 会检查存储分区中的对象,以确定目标网址是对象名称还是文件夹。例如,假设存在以下命令,其中
your-file
是文件的名称:gsutil cp your-file gs://your-bucket/abc
gsutil 会使用
/
分隔符和前缀=abc
针对your-bucket
发出对象列出请求,以确定存储分区中是否有路径以gs://your-bucket/abc/
开头的对象。如果有,gsutil 会将gs://your-bucket/abc
视为文件夹名称,并且上述命令会创建对象gs://your-bucket/abc/your-file
。否则,gsutil 会创建对象gs://your-bucket/abc
。
gsutil 基于规则的方法与许多工具的工作方式不同,后者会创建 0 字节对象来标记文件夹的存在。gsutil 可理解此类工具使用的多种惯例,例如添加 _$folder$
到 0 字节对象名称末尾的惯例,但 gsutil 不需要此类标记对象来实现与 UNIX 命令一致的命名行为。
重试和命名
如果您通过 gsutil 启用自动重试功能,则可能会遇到以下问题:第一次尝试仅会复制部分文件,而后续尝试则会遇到已有的目标文件夹,并且没有正确命名对象。
例如,假设存在以下命令,其中 your-dir/
下存在子文件夹(如 dir1
和 dir2
),这两个子文件夹都包含文件 abc
:
gsutil cp -r ./your-dir gs://your-bucket/new
如果 gs://your-bucket/new
尚不存在,gsutil 会在第一次尝试成功时创建以下对象:
gs://your-bucket/new/dir1/abc gs://your-bucket/new/dir2/abc
在下一次尝试成功时,gsutil 会创建以下对象:
gs://your-bucket/new/your-dir/dir1/abc gs://your-bucket/new/your-dir/dir2/abc
如需让 gsutil 在每次尝试时都保持一致性,请尝试以下操作:
在目标网址的末尾添加斜杠,以便 gsutil 始终将其视为文件夹。
使用
gsutil rsync
。由于 rsync 不使用 Unix cp 定义的文件夹命名规则,因此无论目标子文件夹是否存在,它都会以一致的方式运行。如果 gsutil rsync 不起作用,请创建占位符对象,以确定目标位置是文件夹。例如:
gsutil cp some-file gs://your-bucket/new/placeholder
在存在该占位符对象的情况下,运行以上
gsutil cp -r
命令会始终将gs://your-bucket/new
视为文件夹。当您在gs://your-bucket/new
下至少有一个对象后,可以删除该占位符对象并继续上传。
如需详细了解构建名称的方式,请参阅 gsutil help cp
。
补充说明
您无法使用 gsutil 创建零字节对象来模拟空文件夹。
如果您使用脚本通过组合子路径来构建文件路径,请注意,由于
/
只是位于对象名称中的字符,因此 gsutil 将gs://my-bucket/folder/
解释为与gs://my-bucket//folder
不同的对象。
价格注意事项
gsutil 命名方法的一个缺点是,在执行 cp
或 mv
命令(例如将文件夹以递归方式复制到云端)之前,它需要额外的对象列表。不过,这些列表的成本相对较低,因为它们使用分隔符和前缀参数来限制结果数据。此外,gsutil 仅针对每个 cp
或 mv
命令发出一个对象列表请求,从而在所有传输的对象中分摊费用。
REST API
JSON API
JSON API 中不存在文件夹,但您可以使用prefix
和delimiter
查询参数缩小列出的对象。
例如,如需列出存储桶 my-bucket
中前缀为 folder/subfolder/
的所有对象,请使用以下网址发出对象列出请求:
"https://storage.googleapis.com/storage/v1/b/my-bucket/o?prefix=folder/subfolder/"
XML API
XML API 中不存在文件夹,但您可以使用prefix
和delimiter
查询参数缩小搜索范围列出的对象。
例如,如需列出存储桶 my-bucket
中前缀为 folder/subfolder/
的所有对象,请使用以下网址发出对象列出请求:
"https://storage.googleapis.com/my-bucket?prefix=folder/subfolder/"
后续步骤
- 将对象上传到 Cloud Storage 存储桶。
- 了解 Cloud Storage 中的关键术语。