对 gzip 压缩文件进行转码

本页面介绍如何将文件转换为 gzip 压缩状态以及如何对处于此状态的文件进行转换。在此页面中,您可以简单了解 Cloud Storage 中的转码、使用关联元数据的最佳做法以及压缩文件行为。

转码和 gzip

gzip 是一种数据压缩形式:它通常会减小文件的大小。这样,文件就能够传输得更快,并且占用的存储空间也会更少(相较于未经压缩的文件)。对文件进行压缩可以降低成本并缩短传输时间。在 Cloud Storage 中,转码是指系统在将文件传送给请求者之前自动更改文件的压缩状态。如果转码生成的文件是 gzip 压缩文件,则可视为压缩式转码,而如果生成的文件已不再是 gzip 压缩文件,则可视为解压缩式转码。Cloud Storage 支持解压缩形式的转码。

解压缩式转码

如果文件是以 gzip 压缩对象形式存储在 Cloud Storage 上,系统可在将这些文件发送给请求者之前自动对其进行解压缩,从而生成一个带有标识编码的文件(即未压缩文件)。这样可以减少对象在 Cloud Storage 中的存储费用,但可为请求者提供未经过任何压缩的原始文件。例如,在向客户传送文件时,解压缩式编码会很有用。

要使某个对象能够进行解压缩式转码,该对象必须满足以下两个条件:

  1. 文件必须以 gzip 压缩形式存储在 Cloud Storage 中。

  2. 关联元数据必须包含 Content-Encoding: gzip

如果某个对象满足上述两个条件,系统会在出现请求时对其进行解压缩式转码,在这种情况下,若没有 Content-Encoding 标头,系统也会传送该对象。如果您希望满足上述两个条件的某个对象以压缩状态传送(例如,以便降低出站流量费用或缩短时间),可通过以下两种方式阻止系统执行解压缩式转码:

  • 如果为该对象发出的请求包括 Accept-Encoding: gzip 标头,系统将在此特定请求中原样传送该对象和一个 Content-Encoding: gzip 响应标头。

  • 如果该对象的 Cache-Control 元数据字段设置为 no-transform,则无论 Accept-Encoding 请求标头为何,该对象在所有后续请求中都将以压缩对象形式传送。

Content-Type 与 Content-Encoding

若要了解 Content-TypeContent-Encoding 与转码之间如何相互关联,您应了解几种相关行为。二者都是随对象一起存储的元数据。有关如何向对象添加元数据的分步说明,请参阅查看和修改对象元数据

Content-Type 应包含在所有上传中,并指明上传对象的类型。例如:

Content-Type: text/plain

以上内容表示上传的对象是纯文本文件。系统不会执行任何检查来确保指定 Content-Type 与所上传对象的实际性质相匹配,但如果指定的对象类型不正确,这不仅会导致请求者接收不到预期内容,而且可能引发意外行为。

Content-Encoding 是可选项;如果需要,您可在上传压缩文件时添加此项。例如:

Content-Encoding: gzip

以上内容表示上传的对象已经过 gzip 压缩。和 Content-Type 一样,系统不会执行任何检查来确保指定 Content-Encoding 实际应用于所上传的对象,因此如果指定的对象编码不正确,可能会导致后续下载请求发生意外行为。

建议做法

  • 上传 gzip 压缩对象时,建议您在设置元数据时同时指定 Content-TypeContent-Encoding 两项。例如,对于压缩的纯文本文件,请指定以下内容:

    Content-Type: text/plain
    Content-Encoding: gzip
    

    该设置可让所有访问该对象的人员详细了解其状态。此外,这样操作之后,对象将能够在日后的下载中执行解压缩式转码,从而让客户端应用得以正确处理 Content-Type 的语义。

  • 或者,您也可以在上传对象时设置 Content-Type(以指示压缩),而不指定 Content-Encoding。例如:

    Content-Type: application/gzip
    

    但在这种情况下,请求者只能直接了解该对象已经过 gzip 压缩,而无法获取关于基础对象类型的信息。此外,该对象也将无法执行解压缩式转码。

不建议的做法

  • 尽管您在上传经过 gzip 压缩的文件时可以忽略该文件的压缩性质,但建议您不要这样做。例如,对于 gzip 压缩的纯文本文件,应避免仅设置 Content-Type: text/plain。否则会导致对象状态被曲解,因为对象将传送给请求者。

  • 同样,上传对象时不应忽略 Content-Type,即使包含 Content-Encoding 也是如此。否则可能会导致 Content-Type 被设置为默认值,但也可能会导致请求被拒绝,具体取决于上传方式。

错误做法

  • 设置元数据时不应以冗余方式报告对象的压缩状态:

    Content-Type: application/gzip
    Content-Encoding: gzip
    

    此设置表示,您所上传的 gzip 压缩对象已经过二次 gzip 压缩,而实际情况通常并非如此(如果您真的打算对某个文件进行双重压缩,请参阅下面的对压缩对象使用 gzip 部分)。如果此类错误报告对象发生解压缩式转码,该对象在传送时将采用标识编码,但请求者仍然会认为自己收到的对象具有一个关联的压缩层。尝试解压缩该对象时,操作将会失败。

  • 同样,上传未经 gzip 压缩的文件时不应使用 Content-Encoding: gzip。否则会使对象显示为符合转码条件,但当对该对象发出请求时,尝试转码的操作将会失败。

对压缩对象使用 gzip

某些对象(例如许多视频、音频和图片文件)已进行压缩处理,更不用说 gzip 文件本身了。对此类对象使用 gzip 实际上没有任何好处:在几乎所有情况下,由于 gzip 开销,这样做都会使对象变得更大。为此,通常不鼓励对已经压缩的内容使用 gzip,以防导致意外行为。

例如,尽管 Cloud Storage 允许上传和存储“双重压缩”对象(即不但对象本身已经过 gzip 压缩,而且其基础 Content-Type 本身也进行了压缩),但它不允许以双重压缩状态传送对象,除非对象的 Cache-Control 元数据包含 no-transform。Cloud Storage 会移除最外层的 gzip 压缩,删除 Content-Encoding 响应标头,并传送生成的对象。即使是使用 Accept-Encoding: gzip 发出的请求也是如此。

使用 Range 标头

发生转码时,如果对象请求包含 Range 标头,系统则会静默地忽略该标头。这意味着针对部分内容的请求没有完成,而响应改为传送整个请求对象。出现这种行为的原因在于,没有事先完整地解压缩文件,从而导致无法从压缩文件中选择某一范围:针对部分文件内容的每个请求都将伴随着对整个文件(可能很大)的解压缩操作,这会导致资源利用率不佳。您应该了解这种行为并避免在使用转码时使用 Range 标头,因为传输整个对象(而不只是请求的范围)会产生费用。如需详细了解使用 Range 标头发出请求时允许的响应行为,请参阅规范

如果您需要使用 Range 标头发出请求,应确保请求的对象不会发生转码。要实现此目标,您可以在上传对象时首先选择适当的属性。例如,对于具有 Content-Type: application/gzip 而没有 Content-Encoding 的对象,应根据要求执行范围请求。

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Cloud Storage
需要帮助?请访问我们的支持页面