限定最后修改时间或ETag下载OSS文件

在下载文件时,通过使用条件如最后修改时间或ETag来限制下载,可以确保只有在文件有更新时才执行下载。如果条件不满足,系统将返回错误而不会下载文件。这种方法可以避免重复下载未更改的文件,从而减少网络流量和资源使用,提高下载效率。

前提条件

  • 已上传文件到OSS。具体操作,请参见上传文件

  • 如果要下载归档存储类型的Object,请确保该Object已进入解冻状态或Bucket已开启归档直读。具体操作,请参见解冻Object归档直读

  • 如果要下载冷归档存储或者深度冷归档存储类型的Object,请确保该Object已进入解冻状态。具体操作,请参见解冻Object

  • 已具有oss:GetObject权限。具体操作,请参见RAM Policy常见示例

使用场景

  • 应用资源更新:应用仅在检测到OSS文件ETag变更或最后修改时间更新时下载新资源,最小化数据使用,优化用户体验。

  • 数据同步与增量备份:基于OSS的最后修改时间或ETag,确保只同步或备份更改过的文件,节省带宽,保障数据的时效性和一致性。

  • 文件共享和同步:使用ETag或最后修改时间进行验证,仅在必要时同步文件,加速协作,降低数据消耗。

限定条件

OSS支持的限定条件如下:

参数

描述

If-Modified-Since

如果指定的时间早于实际修改时间或指定的时间不符合规范,则直接返回Object,并返回200 OK;如果指定的时间等于或者晚于实际修改时间,则返回304 Not Modified。

时间格式:GMT,例如Fri, 13 Nov 2015 14:47:53 GMT

默认值:无

If-Unmodified-Since

如果指定的时间等于或者晚于Object实际修改时间,则正常传输Object,并返回200 OK;如果指定的时间早于实际修改时间,则返回412 Precondition Failed。

时间格式:GMT,例如Fri, 13 Nov 2015 14:47:53 GMT

If-Modified-SinceIf-Unmodified-Since可以同时使用。

默认值:无

If-Match

如果传入的ETagObjectETag匹配,则正常传输Object,并返回200 OK;如果传入的ETagObjectETag不匹配,则返回412 Precondition Failed。

ObjectETag值用于验证数据是否发生了更改,您可以基于ETag值验证数据完整性。

默认值:无

If-None-Match

如果传入的ETag值和ObjectETag不匹配,则正常传输Object,并返回200 OK;如果传入的ETagObjectETag匹配,则返回304 Not Modified。

If-MatchIf-None-Match可以同时使用。

默认值:无

重要

OSS控制台、命令行工具ossutil不支持限定条件下载。

操作步骤

使用阿里云SDK

以下仅列举部分SDK使用GetObject接口限定条件下载的代码示例。关于其他限定条件下载的代码示例,请参见SDK简介

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GetObjectRequest;
import java.io.File;
import java.util.Date;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写不包含Bucket名称在内的Object完整路径,例如testfolder/exampleobject.txt。
        String objectName = "testfolder/exampleobject.txt";
        String pathName = "D:\\localpath\\examplefile.txt";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            GetObjectRequest request = new GetObjectRequest(bucketName, objectName);
            // 假设Object最后修改时间为2023年9月26日13:27:04,当填写早于该时间的Data对象时(例如Tue Sep 25 13:27:04 CST 2023),将满足If-Modified-Since的限定条件,并触发下载行为。
            request.setModifiedSinceConstraint(new Date("Tue Sep 25 13:27:04 CST 2023"));

            // 下载OSS文件到本地文件。
            ossClient.getObject(request, new File(pathName));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
        

PHP

<?php

// 引入自动加载文件,确保依赖库能够正确加载
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定义命令行参数的描述信息
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地域(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 访问域名(可选)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名称(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 对象名称(必填)
];

// 将参数描述转换为getopt所需的长选项格式
// 每个参数后面加上":"表示该参数需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令行参数
$options = getopt("", $longopts);

// 验证必填参数是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 获取参数的帮助信息
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填参数缺失,则退出程序
    }
}

// 从解析的参数中提取值
$region = $options["region"]; // Bucket所在的地域
$bucket = $options["bucket"]; // Bucket名称
$key = $options["key"];       // 对象名称

// 加载环境变量中的凭证信息
// 使用EnvironmentVariableCredentialsProvider从环境变量中读取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 设置凭证提供者
$cfg->setRegion($region); // 设置Bucket所在的地域
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了访问域名,则设置endpoint
}

// 创建OSS客户端实例
$client = new Oss\Client($cfg);

// 假设Object最后修改时间为2024年10月21日18:43:02,则填写的UTC早于该时间时,将满足IfModifiedSince的限定条件,并触发下载行为
$ifModifiedSince = "Sun, 21 Oct 2024 18:43:02 GMT";

// 假设ETag为e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,则填写的ETag与Object的ETag值相等时,将满足IfMatch的限定条件,并触发下载行为
$etag = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";

// 创建GetObjectRequest对象,用于获取指定对象的内容
$request = new Oss\Models\GetObjectRequest(
            bucket: $bucket,
            key: $key,
            ifModifiedSince: $ifModifiedSince,
            ifMatch: $etag);

// 执行获取对象操作
$result = $client->getObject($request);

// 打印获取结果
// 输出HTTP状态码、请求ID以及对象的内容
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP状态码,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL . // 请求ID,用于调试或追踪请求
    'object content:' . $result->body->getContents() . PHP_EOL // 对象的内容
);

Node.js

const OSS = require('ali-oss');

const client = new OSS({
  // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: 'yourRegion',
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // 填写Bucket名称。
  bucket: 'examplebucket'
});

async function main() {
  try {
    // 向目标Bucket上传名为exampleobject.txt的文件,文件内容自定义。
    await client.put("exampleobject.txt", Buffer.from("contenttest"));
    // 在请求头If-Modified-Since中指定时间,如果指定的时间早于文件实际修改时间,则下载文件。
    let result = await client.get("exampleobject.txt", {
      headers: {
        "If-Modified-Since": new Date("1970-01-01").toGMTString(),
      },
    });
    console.log(result.content.toString() === "contenttest");
    console.log(result.res.status === 200);

    // 如果指定的时间等于或者晚于文件实际修改时间,则返回304 Not Modified。
    result = await client.get("exampleobject.txt", {
      headers: {
        "If-Modified-Since": new Date().toGMTString(),
      },
    });
    console.log(result.content.toString() === "");
    console.log(result.res.status === 304);
  } catch (e) {
    console.log(e.code === "Not Modified");
  }
}

main();

Python

import argparse
import alibabacloud_oss_v2 as oss
from datetime import datetime, timezone

# 创建一个命令行参数解析器,并描述脚本用途:获取对象并保存到文件示例
parser = argparse.ArgumentParser(description="get object to file sample")

# 添加命令行参数 --region,表示存储空间所在的区域,必需参数
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令行参数 --bucket,表示要获取对象的存储空间名称,必需参数
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令行参数 --endpoint,表示其他服务可用来访问OSS的域名,非必需参数
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令行参数 --key,表示对象(文件)在OSS中的键名,必需参数
parser.add_argument('--key', help='The name of the object.', required=True)
# 添加命令行参数 --file_path,表示下载文件的本地路径,必需参数
parser.add_argument('--file_path', help='The path of the file to save the downloaded content.', required=True)

def main():
    # 解析命令行提供的参数,获取用户输入的值
    args = parser.parse_args()

    # 从环境变量中加载访问OSS所需的认证信息,用于身份验证
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的默认配置创建配置对象,并设置认证提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # 设置配置对象的区域属性,根据用户提供的命令行参数
    cfg.region = args.region

    # 如果提供了自定义endpoint,则更新配置对象中的endpoint属性
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用上述配置初始化OSS客户端,准备与OSS交互
    client = oss.Client(cfg)

    # 定义 if_modified_since 时间
    # 只有在此时间之后被修改的对象才会被返回
    if_modified_since = datetime(2024, 10, 1, 12, 0, 0, tzinfo=timezone.utc)

    # 假设ETag为DA5223EFCD7E0353BE08866700000000,则填写的ETag与Object的ETag值相等时,将满足IfMatch的限定条件,并触发下载行为。
    etag = "\"DA5223EFCD7E0353BE08866700000000\""

    # 执行获取对象并保存到本地文件的请求
    result = client.get_object_to_file(
        oss.GetObjectRequest(
            bucket=args.bucket,  # 指定存储空间名称
            key=args.key,        # 指定对象键名
            if_modified_since=if_modified_since,  # 只有在指定时间之后被修改的对象才会被返回
            if_match=etag,       # 只有 ETag 匹配的对象才会被返回
        ),
        args.file_path  # 指定下载文件的本地路径
    )

    # 输出获取对象的结果信息,包括状态码、请求ID等
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' content length: {result.content_length},'
          f' content range: {result.content_range},'
          f' content type: {result.content_type},'
          f' etag: {result.etag},'
          f' last modified: {result.last_modified},'
          f' content md5: {result.content_md5},'
          f' cache control: {result.cache_control},'
          f' content disposition: {result.content_disposition},'
          f' content encoding: {result.content_encoding},'
          f' expires: {result.expires},'
          f' hash crc64: {result.hash_crc64},'
          f' storage class: {result.storage_class},'
          f' object type: {result.object_type},'
          f' version id: {result.version_id},'
          f' tagging count: {result.tagging_count},'
          f' server side encryption: {result.server_side_encryption},'
          f' server side data encryption: {result.server_side_data_encryption},'
          f' next append position: {result.next_append_position},'
          f' expiration: {result.expiration},'
          f' restore: {result.restore},'
          f' process status: {result.process_status},'
          f' delete marker: {result.delete_marker},'
          f' server time: {result.headers.get("x-oss-server-time")},'
    )

# 当此脚本被直接执行时,调用main函数开始处理逻辑
if __name__ == "__main__":
    main()  # 脚本入口点,控制程序流程从这里开始

Browser.js

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Document</title>
</head>

<body>
  <button id='upload'>上传</button>
  <button id='download'>下载</button>
    <!--导入SDK文件-->
  <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
  <script type="text/javascript">
      const client = new OSS({
         // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
         region: 'yourRegion',
         authorizationV4: true,
         // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
         accessKeyId: 'yourAccessKeyId',
         accessKeySecret: 'yourAccessKeySecret',
         // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: 'yourSecurityToken',
        // 填写Bucket名称,例如examplebucket。
        bucket: "examplebucket",
      });

    const download = document.getElementById('download')
    const upload = document.getElementById('upload')

    // 上传文件。  
    upload.addEventListener('click', () => {
      // 指定待上传的文件内容。
      const file = new Blob(['examplecontent'])
      // 指定待上传文件的完整路径,例如exampledir/exampleobject.txt。
      const fileName = 'exampledir/exampleobject.txt'
      const result = client.put(fileName, file).then(r => console.log(r))
    })

    // 下载文件。
    download.addEventListener('click', () => {
      // 指定待下载的字节范围。
      const start = 1, end = 5
      client.get('exampledir/exampleobject.txt', {
        headers: {
          // 在请求头If-Modified-Since中指定时间,如果指定的时间早于文件实际修改时间,则下载文件。如果指定的时间等于或者晚于文件实际修改时间,则返回304 Not Modified。
          "If-Modified-Since": new Date("1970-01-01").toGMTString()
          // 在请求头If-Unmodified-Since中指定时间,如果指定的时间等于或者晚于文件实际修改时间,则下载文件。如果指定的时间早于文件实际修改时间,则返回412 Precondition Failed。
          //"If-Unmodified-Since": new Date(1970-01-01).toGMTString()
          // 在请求头If-Match中传入ETag,如果传入的ETag和文件的ETag匹配,则下载文件。如果传入的ETag和文件的ETag不匹配,则返回412 Precondition Failed。
          //"If-Match": '5B3C1A2E0563E1B002CC607C****'
          // 在请求头If-None-Match中传入ETag,如果传入的ETag和文件的ETag不匹配,则下载文件。如果传入的ETag和文件的ETag匹配,则返回304 Not Modified。
          //"If-None-Match": '5B3C1A2E0563E1B002CC607C****'
        },
      }).then(r => {
        if (r.content.length > 0) {                
          const newBlob = new Blob([r.content], { type: r.res.headers['content-type'] });
          const link = document.createElement('a')
          link.href = window.URL.createObjectURL(newBlob)
          link.download = 'foo.txt'
          link.click()
          window.URL.revokeObjectURL(link.href)
        } else {
          console.log('错误码', r.res.status)
          console.log('没有符合条件的下载项')
        }
      })
    })

  </script>
</body>

</html>

Android

// 依次填写Bucket名称(例如examplebucket)、Object完整路径(例如exampledir/exampleobject.txt)。
// Object完整路径中不能包含Bucket名称。
String bucketName = "examplebucket";
String objectKey = "exampledir/exampleobject.txt";
// 构造下载文件请求。
Map<String, String> headers = new HashMap<>();
// 如果指定的时间早于实际修改时间,则正常传输文件,否则返回错误(304 Not modified)。
headers.put(OSSHeaders.GET_OBJECT_IF_MODIFIED_SINCE, "Fri, 13 Nov 2015 14:47:53 GMT");
// 如果指定的时间等于或者晚于文件实际修改时间,则正常传输文件,否则返回错误(412 Precondition failed)
// headers.put(OSSHeaders.GET_OBJECT_IF_UNMODIFIED_SINCE, "Fri, 13 Nov 2015 14:47:53 GMT");
// 如果指定的ETag和OSS文件的ETag匹配,则正常传输文件,否则返回错误(412 Precondition failed)
// headers.put(OSSHeaders.GET_OBJECT_IF_MATCH, "5B3C1A2E0563E1B002CC607C*****");
// 如果指定的ETag和OSS文件的ETag不匹配,则正常传输文件,否则返回错误(304 Not modified)
// headers.put(OSSHeaders.GET_OBJECT_IF_NONE_MATCH, "5B3C1A2E0563E1B002CC607C*****");
GetObjectRequest get = new GetObjectRequest(bucketName, objectKey);
get.setRequestHeaders(headers);

OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
    @Override
    public void onSuccess(GetObjectRequest request, GetObjectResult result) {
        // 请求成功。
        InputStream inputStream = result.getObjectContent();
        byte[] buffer = new byte[2048];
        int len;
        try {
            while ((len = inputStream.read(buffer)) != -1) {
                // 处理下载的数据。
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 请求异常。
        if (clientExcepion != null) {
            // 本地异常如网络异常等。
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // 服务异常。
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

Go

package main

import (
	"context"
	"flag"
	"log"
	"net/http"
	"time"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定义全局变量
var (
	region     string // 存储区域
	bucketName string // 存储空间名称
	objectName string // 对象名称
)

// init函数用于初始化命令行参数
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令行参数
	flag.Parse()

	// 检查bucket名称是否为空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 检查region是否为空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 检查object名称是否为空
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 加载默认配置并设置凭证提供者和区域
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 创建OSS客户端
	client := oss.NewClient(cfg)

	// 指定本地文件路径
	localFile := "download.file"

	// 假设Object最后修改时间为2024年10月21日18:43:02,则填写的UTC早于该时间时,将满足IfModifiedSince的限定条件,并触发下载行为。
	date := time.Date(2024, time.October, 21, 18, 43, 2, 0, time.UTC)

	// 假设ETag为e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,则填写的ETag与Object的ETag值相等时,将满足IfMatch的限定条件,并触发下载行为。
	etag := "\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\""

	// 创建下载对象到本地文件的请求
	getRequest := &oss.GetObjectRequest{
		Bucket:          oss.Ptr(bucketName),                   // 存储空间名称
		Key:             oss.Ptr(objectName),                   // 对象名称
		IfModifiedSince: oss.Ptr(date.Format(http.TimeFormat)), // 指定IfModifiedSince参数
		IfMatch:         oss.Ptr(etag),                         // 指定IfMatch参数
	}

	// 执行下载对象到本地文件的操作并处理结果
	result, err := client.GetObjectToFile(context.TODO(), getRequest, localFile)
	if err != nil {
		log.Fatalf("failed to get object to file %v", err)
	}

	log.Printf("get object to file result:%#v\n", result)
}

iOS

OSSGetObjectRequest *get = [OSSGetObjectRequest new];
// 填写Bucket名称。关于Bucket名称命名规范的更多信息,请参见Bucket。
get.bucketName = @"examplebucket";
// 填写不包含Bucket名称在内的Object完整路径。关于Object名称命名规范的更多信息,请参见Object。
get.objectKey = @"exampledir/exampleobject.txt";
NSMutableDictionary *headerFields = [NSMutableDictionary dictionary];
// 指定下载实际修改时间晚于Fri, 13 Oct 2021 14:47:53 GMT的Object。
[headerFields setValue:@"Fri, 13 Oct 2021 14:47:53 GMT" forKey:@"If-Modified-Since"];
// 指定下载实际修改时间早于或者等于当前时间的Object。
[headerFields setValue:[[NSDate new] oss_asStringValue] forKey:@"If-Unmodified-Since"];
// 指定下载与传入的ETag值不匹配的Object。
[headerFields setValue:@"5B3C1A2E0563E1B002CC607C****" forKey:@"If-None-Match"];
// 指定下载与传入的ETag值匹配的Object。
[headerFields setValue:@"fba9dede5f27731c9771645a3986****" forKey:@"If-Match"];
get.headerFields = headerFields;

[[[client getObject:get] continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    if (!task.error) {
        NSLog(@"get object success!");
    } else {
        NSLog(@"get object error: %@", task.error);
    }
    return nil;
}] waitUntilFinished];

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见GetObject

相关文档

  • 如何在开启了版本控制的Bucket中下载文件,请参见开启版本控制下Object的操作

  • 如何在暂停了版本控制的Bucket中下载文件,请参见暂停版本控制下Object的操作

  • 为了防止第三方未经授权从您的Bucket里下载数据,OSS提供了BucketObject级别的访问权限控制。更多信息,请参见权限控制

  • 如果您希望直接下载文件,您可以使用简单下载。具体操作,请参见简单下载

  • 如果您希望在下载大文件过程中,从下载中断的位置继续下载未完成的部分,您可以使用断点续传。具体操作,请参见断点续传下载

  • 如果您希望将私有BucketObject提供给第三方进行下载,请通过STS临时访问凭证或签名URL的方式授权第三方下载文件。具体操作,请参见授权给第三方下载