添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 开发指南
    1. 安全机制
      1. 上传策略
      2. 上传凭证
      3. 下载凭证
      4. 管理凭证
        1. 管理凭证历史文档
    2. 上传资源
      1. 表单上传
      2. 分片上传 v1 版
      3. 分片上传 v2 版
      4. 简单反馈
      5. 回调通知
      6. 303 重定向
      7. 异步数据预处理
      8. 自定义响应内容
      9. 变量
    3. 下载资源
      1. 公开资源下载
      2. 私有资源下载
      3. 防盗链
      4. 下载设置
      5. 高级下载
    4. 管理存储空间
      1. 绑定源站域名
      2. 访问控制
      3. 静态页面管理
      4. 空间备注
      5. 文件客户端缓存
      6. 重定向
      7. 空间标签
      8. 空间授权
      9. 跨域资源共享
      10. 生命周期管理
      11. 事件通知
      12. 镜像回源
      13. 跨区域同步
      14. 空间访问日志
      15. 删除空间
    5. 数据安全
      1. Referer 防盗链
      2. 对象锁定
    6. 数据处理
      1. 图片处理
      2. 实时转码(边转边播)
      3. 原始资源保护
      4. 数据工作流
      5. 图片压缩格式自适应
      6. CDN 热点视频瘦身
    7. 传输加速
    8. AWS S3 兼容
      1. 存储类型
      2. 服务域名
      3. 签名认证
      4. 临时安全凭证
      5. 兼容公共头
      6. 兼容 API
        1. 使用 Bucket Policy 授权
      7. 兼容 SDK 示例
        1. AWS SDK for C++
        2. AWS SDK for .NET
        3. AWS SDK for Go
        4. AWS SDK for Java
        5. AWS SDK for JavaScript
        6. AWS SDK for Kotlin
        7. AWS SDK for PHP
        8. AWS SDK for Python
        9. AWS SDK for Ruby
        10. AWS SDK for Rust
        11. AWS SDK for Swift
      8. 兼容工具示例
        1. AWS CLI
        2. CloudBerry Explorer
        3. S3 Browser
        4. S3FS
    9. 附录
  • 控制台指南
    1. 控制台概览
    2. 空间管理
      1. 新建空间
      2. 空间列表管理
      3. 空间概览
      4. 空间设置
        1. 设置访问控制
        2. 设置静态页面
        3. 设置空间备注
        4. 设置文件客户端缓存
        5. 设置重定向
        6. 设置标签管理
        7. 设置空间授权
        8. 设置Referer防盗链
        9. 设置跨域资源共享
        10. 设置生命周期
        11. 设置事件通知
        12. 设置镜像回源
        13. 设置对象锁定
        14. 设置空间日志
        15. 设置空间内容审核
        16. 设置传输加速
        17. 删除存储空间
      5. 域名管理
        1. 设置自定义CDN加速域名
        2. 设置自定义源站域名
      6. 数据处理
        1. 多媒体样式
          1. 设置图片样式
          2. 设置视频样式
          3. 设置原始资源保护
        2. 任务与工作流
          1. 任务管理
          2. 任务触发器
          3. 工作流模板
          4. 预设集管理
            1. 普通转码
            2. 锐智转码
            3. 视频水印
            4. 视频截图
            5. 音视频拼接
    3. 文件管理
      1. 上传文件
      2. 创建目录
      3. 搜索文件
      4. 修改文件名
      5. 修改文件类型
      6. 查看文件详情
      7. 设置文件元信息
      8. 下载文件
      9. 分享文件
      10. 分享目录
      11. 刷新 CDN 缓存
      12. 移动文件
      13. 删除文件
      14. 删除目录
      15. 修改文件存储类型
      16. 解冻文件
      17. 任务中心
    4. 设置跨区域同步
    5. 统计分析
    6. 存储安全
      1. 内容审核
      2. 违规列表
    7. 设置数据迁移
  • API 文档
  • API 概览
  • HTTP Headers
  • 错误响应
  • 数据格式
  • Service 接口
    1. 获取 Bucket 列表
  • Bucket 接口
    1. 创建 Bucket
    2. 删除 Bucket
    3. 获取 Bucket 空间域名
    4. 设置 Bucket 镜像源
    5. 设置 Bucket 访问权限
    6. 设置空间标签
    7. 查询空间标签
    8. 删除空间标签
  • Object 接口
    1. 直传文件
    2. 分片上传 v1 版
      1. 创建块
      2. 上传片
      3. 创建文件
    3. 分片上传 v2 版
      1. 初始化任务
      2. 分块上传数据
      3. 完成文件上传
      4. 终止上传
      5. 列举已上传分片
    4. 资源列举
    5. 资源元信息查询
    6. 资源元信息修改
    7. 资源移动/重命名
    8. 资源复制
    9. 资源删除
    10. 批量操作
    11. 修改文件状态
    12. 修改文件存储类型
    13. 解冻归档/深度归档存储文件
    14. 修改文件过期删除时间
    15. 修改文件生命周期
    16. 镜像资源更新
    17. 异步第三方资源抓取
  • 数据统计接口
  • SDK 下载
  • 鸿蒙(Harmony) SDK
  • Android SDK
    1. Android SDK历史文档
      1. Android SDK V7
  • C/C++ SDK
  • C# SDK
    1. C# SDK v7.2.15 文档
    2. C# SDK v7.0 文档
    3. C# SDK v6 文档
  • Flutter SDK
  • Go SDK
    1. Go SDK历史版本
  • Java SDK
    1. Java SDK 历史文档
  • JavaScript SDK
    1. JavaScript SDK历史文档2.x
    2. JavaScript SDK历史文档1.x
  • Node.js SDK
    1. Node.js SDK V6
  • Objective-C SDK
  • PHP SDK
    1. PHP SDK历史文档
  • Python SDK
  • Ruby SDK
  • Rust SDK
  • SDK 隐私政策
  • 图形化工具 Kodo Browser
  • 命令行工具 Qshell
  • 数据迁移工具 Kodoimport
  • 检测工具
    1. 上传测试页面
    2. 网络检测工具 Qwebtest
  • Qiniu Jenkins Plugin
  • 数据安全最佳实践
    1. 保障安全上传、下载、管理数据
    2. 降低因账号密码泄露带来的未授权访问风险
    3. 降低被恶意篡改数据的风险
    4. 防止恶意文件上传
    5. 降低被恶意访问、盗量的风险
    6. 降低或因误操作导致的数据丢失的风险
    7. 跟踪、追溯对数据的关键操作
    8. 敏感数据安全防护
  • 文件系统挂载存储桶
  • 在容器中挂载存储桶
  • 数据备份
  • 数据迁移
    1. 热数据无缝迁移
    2. 本地数据迁移至 Kodo
    3. 第三方云存储数据迁移至 Kodo
    4. 以 URL 作为源地址的数据迁移至 Kodo
  • 开源软件管理对象存储
    1. 使用 Go CDK 对接对象存储 Kodo
      1. 使用七牛 Go CDK Driver 对接对象存储 Kodo
      2. 使用 Go CDK 通过 S3 协议对接对象存储 Kodo
    2. 使用 Hadoop 管理对象存储 Kodo
      1. 使用 Hadoop S3A 客户端管理对象存储 Kodo
      2. 使用 Hadoop-Kodo 插件管理对象存储 Kodo
    3. 使用 Kubernetes CSI 挂载对象存储 Kodo
    4. 使用 Rclone 命令行工具管理对象存储 Kodo
    5. 使用 Restic 备份工具对接对象存储 Kodo
    6. 使用 Terraform 管理对象存储 Kodo
  • C# SDK 使用指南

    NuGet release

    此 C# SDK 基于 .Net Standard 2.0,适用于 .NET Core 2.0 和 .NET Framework v4.6.1,详情 查看官网 。 基于 七牛云 API 参考手册构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到 七牛云 上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过 七牛云存储 及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。

    C# SDK 属于服务端 SDK 之一,主要有如下功能:

  • 提供生成客户端上传所需的上传凭证的功能
  • 提供文件从服务端直接上 七牛 的功能
  • 提供对 七牛 空间中文件进行管理的功能
  • 提供对 七牛 空间中文件进行处理的功能
  • 提供七牛 CDN 相关的刷新,预取,日志功能
  • c# SDK 项目地址
  • c# SDK 发布地址
  • c# SDK 历史文档
  • 包管理器(NuGet)方式安装
  • 从源码编译
  • 包管理器(NuGet)方式安装

    从 NuGet 来安装,以 Visual Studio 2013/2015 为例(如果您的 Visual Studio 没有安装 NuGet,请先 安装 )。打开 NuGet 程序包管理器搜索 Qiniu 或者在控制台中键入以下命令:

    Install-Package Qiniu
    从源码编译

    当然,您也可以直接从源码编译

    git clone https://github.com/qiniu/csharp-sdk
    

    c# SDK 的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的Access KeySecret Key,这对密钥可以通过如下步骤获得:

  • 点击注册 🔗开通七牛开发者帐号
  • 如果已有账号,直接登录七牛开发者后台,点击这里 🔗查看 Access Key 和 Secret Key
  • 客户端上传凭证
  • 简单上传凭证
  • 覆盖上传凭证
  • 自定义上传回复凭证
  • 带回调业务服务器的凭证
  • 带数据处理的凭证
  • 带自定义参数的凭证
  • 综合上传凭证
  • 服务器直传
  • 构建配置类
  • 文件上传(表单方式)
  • 字节数组上传(表单方式)
  • 数据流上传(表单方式)
  • 文件分片上传(断点续传)
  • 解析自定义回复内容
  • 业务服务器验证存储服务回调
  • 文件上传分为客户端上传(主要是指网页端和移动端等面向终端用户的场景)和服务端上传两种场景,具体可以参考文档业务流程

    服务端 SDK 在上传方面主要提供两种功能,一种是生成客户端上传所需要的上传凭证,另外一种是直接上传文件到云端。

    客户端上传凭证

    客户端(移动端或者 Web 端)上传文件的时候,需要从客户自己的业务服务器获取上传凭证,而这些上传凭证是通过服务端的 SDK 来生成的,然后通过客户自己的业务 API 分发给客户端使用。根据上传的业务需求不同,c# SDK 支持丰富的上传凭证生成方式。

    创建各种上传凭证之前,我们需要定义好其中鉴权对象mac

    Mac mac = new Mac(AccessKey, SecretKey);
    

    简单上传的凭证

    最简单的上传凭证只需要AccessKeySecretKeyBucket就可以。

    PutPolicy putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket;
    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    

    默认情况下,在不指定上传凭证的有效时间情况下,默认有效期为 1 个小时。也可以自行指定上传凭证的有效期,例如:

    //自定义凭证有效期(示例2小时,expires单位为秒,为上传凭证的有效时间)
    PutPolicy putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket;
    putPolicy.SetExpires(7200);
    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    

    覆盖上传的凭证

    覆盖上传除了需要简单上传所需要的信息之外,还需要想进行覆盖的文件名称,这个文件名称同时可是客户端上传代码中指定的文件名,两者必须一致。

    PutPolicy putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket + ":" + Key;
    putPolicy.SetExpires(7200);
    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    

    自定义上传回复的凭证

    默认情况下,文件上传到存储之后,在没有设置returnBody或者回调相关的参数情况下,存储返回给上传端的回复格式为hashkey,例如:

    {"hash":"Ftgm-CkWePC9fzMBTRNmPMhGBcSV","key":"qiniu.jpg"}
    

    有时候我们希望能自定义这个返回的 JSON 格式的内容,可以通过设置returnBody参数来实现,在returnBody中,我们可以使用七牛支持的魔法变量自定义变量

    PutPolicy putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket + ":" + Key;
    putPolicy.ReturnBody = "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"fsiz\":$(fsize),\"bucket\":\"$(bucket)\",\"name\":\"$(x:name)\"}";
    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    

    则文件上传到存储之后,收到的回复内容如下:

    {"key":"qiniu.jpg","hash":"Ftgm-CkWePC9fzMBTRNmPMhGBcSV","bucket":"if-bc","fsize":39335,"name":"qiniu"}
    

    带回调业务服务器的凭证

    上面生成的自定义上传回复的上传凭证适用于上传端(无论是客户端还是服务端)和存储服务器之间进行直接交互的情况下。在客户端上传的场景之下,有时候客户端需要在文件上传到存储之后,从业务服务器获取相关的信息,这个时候就要用到存储的上传回调及相关回调参数的设置。

    putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket;
    putPolicy.CallbackUrl = "http://api.example.com/qiniu/upload/callback";
    putPolicy.CallbackBody = "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"fsiz\":$(fsize),\"bucket\":\"$(bucket)\",\"name\":\"$(x:name)\"}";
    putPolicy.CallbackBodyType = "application/json";
    upToken = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    Console.WriteLine(upToken);
    

    在使用了上传回调的情况下,客户端收到的回复就是业务服务器响应七牛的 JSON 格式内容。
    通常情况下,我们建议使用application/json格式来设置callbackBody,保持数据格式的统一性。实际情况下,callbackBody也支持application/x-www-form-urlencoded格式来组织内容,这个主要看业务服务器在接收到callbackBody的内容时如果解析。例如:

    putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket;
    putPolicy.CallbackUrl = "http://api.example.com/qiniu/upload/callback";
    putPolicy.CallbackBody = "key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)&name=$(x:name)";
    upToken = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    Console.WriteLine(upToken);
    

    带数据处理的凭证

    七牛支持在文件上传到七牛之后,立即对其进行多种指令的数据处理,这个只需要在生成的上传凭证中指定相关的处理参数即可。

    putPolicy = new PutPolicy();
    string saveMp4Entry = Base64.UrlSafeBase64Encode(Bucket + ":avthumb_test_target.mp4");
    string saveJpgEntry = Base64.UrlSafeBase64Encode(Bucket + ":vframe_test_target.jpg");
    string avthumbMp4Fop = "avthumb/mp4|saveas/" + saveMp4Entry;
    string vframeJpgFop = "vframe/jpg/offset/1|saveas/" + saveJpgEntry;
    string fops = string.Join(";", new string[] { avthumbMp4Fop, vframeJpgFop });
    putPolicy.Scope = Bucket;
    putPolicy.PersistentOps = fops;
    putPolicy.PersistentPipeline = "video-pipe";
    putPolicy.PersistentNotifyUrl = "http://api.example.com/qiniu/pfop/notify";
    putPolicy.PersistentType = 0; // 任务类型:0: 普通任务 1: 闲时任务(一旦指定闲时任务,就不能指定 persistentPipeline)
    putPolicy.
    upToken = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    Console.WriteLine(upToken);
    
  • 队列 pipeline 请参阅创建私有队列;转码操作具体参数请参阅音视频转码;saveas 请参阅处理结果另存
  • 闲时任务的功能介绍、使用场景、定价,详见 闲时任务策略说明
  • 也可以支持使用工作流模版替代数据处理指令。工作流模板是预先编排好的一系列媒体处理流程(如转码、截图、视频拼接等各类处理),登录 对象存储控制台 进行创建,详情参考工作流模板操作指南PersistentWorkflowTemplateId 对应工作流模板列表的名称字段

    putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket;
    putPolicy.PersistentWorkflowTemplateId = "tempname";
    putPolicy.PersistentPipeline = "video-pipe";
    putPolicy.PersistentNotifyUrl = "http://api.example.com/qiniu/pfop/notify";
    putPolicy.PersistentType = 0; // 任务类型:0: 普通任务 1: 闲时任务(一旦指定闲时任务,就不能指定 persistentPipeline)
    putPolicy.
    upToken = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    Console.WriteLine(upToken);
    
  • 需要注意的是,PersistentWorkflowTemplateIdPersistentOps 两个参数只能二选一。
  • 带自定义参数的凭证

    存储支持客户端上传文件的时候定义一些自定义参数,这些参数可以在returnBodycallbackBody里面和七牛内置支持的魔法变量(即系统变量)通过相同的方式来引用。这些自定义的参数名称必须以x:开头。例如客户端上传的时候指定了自定义的参数x:namex:age分别是stringint类型。那么可以通过下面的方式引用:

    putPolicy.ReturnBody = "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"fsiz\":$(fsize),\"bucket\":\"$(bucket)\",\"name\":\"$(x:name)\"}";
    
    putPolicy.CallbackBody = "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"fsiz\":$(fsize),\"bucket\":\"$(bucket)\",\"name\":\"$(x:name)\"}";
    

    综合上传凭证

    上面的生成上传凭证的方法,都是通过设置上传策略 🔗相关的参数来支持的,这些参数可以通过不同的组合方式来满足不同的业务需求,可以灵活地组织你所需要的上传凭证。

    服务端直传

    服务端直传是指客户利用七牛服务端 SDK 从服务端直接上传文件到存锤,交互的双方一般都在机房里面,所以服务端可以自己生成上传凭证,然后利用 SDK 中的上传逻辑进行上传,最后从七牛云获取上传的结果,这个过程中由于双方都是业务服务器,所以很少利用到上传回调的功能,而是直接自定义returnBody来获取自定义的回复内容。

    构建配置类

    存储支持空间创建在不同的机房,在使用七牛的 C# SDK 中的FormUploaderResumeUploader上传文件之前,必须要构建一个上传用的config对象,在该对象中,可以指定空间对应的zone以及其他的一些影响上传的参数。

    Config config = new Config();
    // 空间对应的机房
    config.Zone = Zone.ZONE_CN_East;
    // 是否使用https域名
    config.UseHttps = true;
    // 上传是否使用cdn加速
    config.UseCdnDomains = true;
    

    其中关于Zone对象和机房的关系如下:

    Zone 对象 putPolicy.DeleteAfterDays = 1; // 生成上传token string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString()); Config config = new Config(); // 设置上传区域 config.Zone = Zone.ZONE_CN_East; // 设置 http 或者 https 上传 config.UseHttps = true; config.UseCdnDomains = true; config.ChunkSize = ChunkUnit.U512K; // 表单上传 FormUploader target = new FormUploader(config); HttpResult result = target.UploadFile(filePath, key, token, null); Console.WriteLine("form upload result: " + result.ToString());

    文件分片上传(断点续传)

    断点续传是在分片上传的基础上实现。SDK 内置两种上传方式:表单上传和分片上传。表单上传使用一个 HTTP POST 请求完成文件的上传,因此比较适合较小的文件。相比而言,分片上传比较适合上传比较大的文件(例如数百 MB 或更大)。
    若需深入了解上传方式之间的区别,请参阅上传类型中 表单上传分片上传 v1 版分片上传 v2 版 接口说明。
    可以选择分片上传版本,推荐 extra.Version = “v2”,表示 分片上传 v2 版,默认分片上传 v1 版。

    Mac mac = new Mac(AccessKey, SecretKey);
    // 上传文件名
    string key = "putty.exe";
    // 本地文件路径
    string filePath = "D:\\tools\\putty.exe";
    // 空间名
    string Bucket = "7qiniu";
    // 设置上传策略
    PutPolicy putPolicy = new PutPolicy();
    putPolicy.Scope = Bucket + ":" + key;
    putPolicy.SetExpires(3600);
    string token = Auth.CreateUploadToken(mac, putPolicy.ToJsonString());
    Config config = new Config();
    // 设置上传区域
    config.Zone = Zone.ZONE_CN_East;
    // 设置 http 或者 https 上传
    config.UseHttps = true;
    config.UseCdnDomains = true;
    config.ChunkSize = ChunkUnit.U512K;
    ResumableUploader target = new ResumableUploader(config);
    PutExtra extra = new PutExtra();
    //设置断点续传进度记录文件
    extra.ResumeRecordFile = ResumeHelper.GetDefaultRecordKey(filePath, key);
    Console.WriteLine("record file:" + extra.ResumeRecordFile);
    extra.ResumeRecordFile = "test.progress";
    //指定分片上传版本,默认分片上传 v1
    extra.Version = "v2";
    // 分片上传 v2 指定 part 大小,默认大小为4MB 分片大小范围为1 MB - 1 GB
    extra.PartSize = 4 * 1024 * 1024;
    // 指定分片并发大小,默认为1
    extra.BlockUploadThreads = 4;
    HttpResult result = target.UploadFile(filePath, key, token, extra);
    Console.WriteLine("resume upload: " + result.ToString());
    

    解析自定义回复内容

    有些情况下,七牛返回给上传端的内容不是默认的hashkey形式,这种情况下,可能出现在自定义returnBody或者自定义了callbackBody的情况下,前者一般是服务端直传的场景,而后者则是接受上传回调的场景,这两种场景之下,都涉及到需要将自定义的回复进行内容解析,一般建议在交互过程中,都采用JSON的方式,这样处理起来方法比较一致,而且JSON的方法最通用,基本上了解回复结构就可以处理,这里不再赘述。

    业务服务器验证存储服务回调

    在上传策略里面设置了上传回调相关参数的时候,存储在文件上传到服务器之后,会主动地向callbackUrl发送 POST 请求的回调,回调的内容为callbackBody模版所定义的内容,如果这个模版里面引用了魔法变量或者自定义变量,那么这些变量会被自动填充对应的值,然后在发送给业务服务器。

    业务服务器在收到来自七牛的回调请求的时候,可以根据请求头部的Authorization字段来进行验证,查看该请求是否是来自七牛的未经篡改的请求,具体可以参考回调鉴权

    注意:业务端服务器回调鉴权的 Content-Type 类型应该与上传策略中指定的 callbackBodyType 相同,默认为 application/x-www-form-urlencoded,当 Content-Type 为 application/x-www-form-urlencoded 时,签名内容必须包括请求内容。当 Content-Type 为 application/json 时,签名内容不包括请求内容。

    Zone zone = new Zone
        SrcUpHosts = new string[1] { "<BucketId>.kodo-accelerate.<RegionId>.qiniucs.com" }, // 这里填写空间级别传输加速域名
    Config config = new Config
        Zone = zone,
        UseHttps = true,
    // 表单上传
    FormUploader formUploader = new FormUploader(config);
    HttpResult result = formUploader.UploadFile(filePath, key, token, null);
    Console.WriteLine("form upload result: " + result.ToString());
    // 分片上传
    ResumableUploader resumableUploader = new ResumableUploader(config);
    HttpResult result = resumableUploader.UploadFile(filePath, key, token, null);
    Console.WriteLine("resumable upload result: " + result.ToString());
    

    文件下载分为公开空间的文件下载和私有空间的文件下载。

    对于公开空间,其访问的链接主要是将空间绑定的域名(可以是存储空间的默认域名或者是绑定的自定义域名)拼接上空间里面的文件名即可访问,标准情况下需要在拼接链接之前,将文件名进行urlencode以兼容不同的字符。

    string domain = "http://if-pbl.qiniudn.com";
    string key = "hello/world/七牛/test.png";
    string publicUrl = DownloadManager.CreatePublishUrl(domain, key);
    Console.WriteLine(publicUrl);
    

    对于私有空间,首先需要按照公开空间的文件访问方式构建对应的公开空间访问链接,然后再对这个链接进行私有授权签名。

    Mac mac = new Mac(AccessKey, SecretKey);
    string domain = "http://if-pri.qiniudn.com";
    string key = "hello/world/七牛/test.png";
    string privateUrl = DownloadManager.CreatePrivateUrl(mac, domain, key, 3600);
    Console.WriteLine(privateUrl);
    

    资源管理包括的主要功能有:

  • 获取文件信息
  • 修改文件 MimeType
  • 修改文件存储类型
  • 移动或重命名文件
  • 复制文件副本
  • 删除空间中的文件
  • 设置或更新文件生存时间
  • 获取指定前缀文件列表
  • 抓取网络资源到空间
  • 更新镜像存储空间中文件内容
  • 资源管理批量操作
  • 批量获取文件信息
  • 批量修改文件类型
  • 批量删除文件
  • 批量复制文件
  • 批量移动或重命名文件
  • 批量更新文件的有效期
  • 批量更新文件存储类型
  • 资源管理相关的操作首先要构建BucketManager对象:

    // 设置存储区域
    Config config = new Config();
    config.Zone = Zone.ZONE_CN_East;
    Mac mac = new Mac(AccessKey, SecretKey);
    BucketManager bucketManager = new BucketManager(mac, config);
    

    获取文件信息

    // 存储空间名
    string Bucket = "7qiniu";
    // 	待查询文件名
    string key = "02.mp4";
    StatResult statRet = bucketManager.Stat(Bucket, key);
    if (statRet.Code != (int)HttpCode.OK)
        Console.WriteLine("stat error: " + statRet.ToString());
    Console.WriteLine(statRet.Result.Hash);
    Console.WriteLine(statRet.Result.MimeType);
    Console.WriteLine(statRet.Result.Fsize);
    Console.WriteLine(statRet.Result.MimeType);
    Console.WriteLine(statRet.Result.FileType);
    

    修改文件 MimeType

    string Bucket = "7qiniu";
    string key = "7qiniu.mp4";
    HttpResult ret = bucketManager.ChangeMime(Bucket, key, "application / mpegurl");
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine("change mime error: " + ret.ToString());
        Console.ReadKey();
    Console.WriteLine(ret.ToString());
    

    修改文件存储类型

    // 存储空间
    string Bucket = "7qiniu";
    // 文件名
    string key = "7qiniu.mp4";
    // newType 为 0 表示普通存储,newType 为 1 表示低频存储,newType 为 2 表示归档存储,newType 为 3 表示深度归档存储,newType 为 4 表示归档直读存储
    int newType = 1;
    HttpResult ret = bucketManager.ChangeType(Bucket, key, newType);
    if (ret.Code != (int)HttpCode.OK && !ret.Text.Contains("already in line stat"))
        Console.WriteLine("change type error: " + ret.ToString());
    Console.WriteLine(ret.ToString());
    

    移动或重命名文件

    移动操作本身支持移动文件到相同,不同空间中,在移动的同时也可以支持文件重命名。唯一的限制条件是,移动的源空间和目标空间必须在同一个机房。

    目标文件名 // 是否设置强制覆盖 Boolean force = true; HttpResult copyRet = bucketManager.move(Bucket, Key, newBucket, newKey, force); if (copyRet.Code != (int)HttpCode.OK) Console.WriteLine("move error: " + moveRet.ToString()); Console.WriteLine(moveRet.ToString());

    复制文件副本

    文件的复制和文件移动其实操作一样,主要的区别是移动后源文件不存在了,而复制的结果是源文件还存在,只是多了一个新的文件副本。

    // 原始空间
    string Bucket = "7qiniu";
    // 原始文件名
    string Key = "0_01.png";
    // 目标空间
    string newBucket = "07qiniu";
    // 目标文件名
    string newKey = "copy0_01.png";
    // 是否设置强制覆盖
    Boolean force = true;
    HttpResult copyRet = bucketManager.copy(Bucket, Key, newBucket, newKey, force);
    if (copyRet.Code != (int)HttpCode.OK)
        Console.WriteLine("copy error: " + copyRet.ToString());
    Console.WriteLine(copyRet.ToString());
    

    删除空间中的文件

    // 空间名
    string Bucket = "7qiniu";
    // 文件名
    string Key = "10138_7e706ac5317f2993176725cbdf50d0e10f079c05.ppt";
    HttpResult deleteRet = bucketManager.Delete(Bucket, Key);
    Console.WriteLine("delete error: " + deleteRet.ToString());
    if (deleteRet.Code != (int)HttpCode.OK)
        Console.WriteLine("delete error: " + deleteRet.ToString());
    

    设置或更新文件的生存时间

    可以给已经存在于空间中的文件设置文件生存时间,或者更新已设置了生存时间但尚未被删除的文件的新的生存时间。

    // 存储空间名
    string Bucket = "7qiniu";
    // 文件名
    string key = "0_01.png";
    HttpResult expireRet = bucketManager.DeleteAfterDays(Bucket, key, 7);
    if (expireRet.Code != (int)HttpCode.OK)
        Console.WriteLine("deleteAfterDays error: " + expireRet.ToString());
    Console.WriteLine(expireRet.ToString());
    

    获取指定前缀的文件列表

    // 空间名
    string Bucket = "7qiniu";
    // 指定前缀,只有资源名匹配该前缀的资源会被列出
    string prefix = "qiniu";
    // 指定目录分隔符,列出所有公共前缀(模拟列出目录效果)
    string delimiter = "";
    // 本次列举的条目数,范围为1-1000
    int limit = 100;
    // 上一次列举返回的位置标记,作为本次列举的起点信息
    string marker = "";
    ListResult listRet = bucketManager.ListFiles(Bucket, prefix, marker, limit, delimiter);
    if (listRet.Code != (int)HttpCode.OK)
        Console.WriteLine("list files error: " + listRet.ToString());
    Console.WriteLine(listRet.ToString());
    

    抓取网络资源到空间

    // 公网可访问的文件链接
    string resUrl = "http://devtools.qiniu.com/qiniu.png";
    // 存储空间名
    string Bucket = "7qiniu";
    // 文件名
    string Key = "qiniu.jpg";
    FetchResult ret = bucketManager.Fetch(resUrl, Bucket, Key);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine("fetch error: " + ret.ToString());
    Console.WriteLine(ret.ToString());
    

    更新镜像空间中存储的文件内容

    // 设置存储空间
    string Bucket = "7qiniu";
    // 文件名
    string key = "333";
    HttpResult ret = bucketManager.Prefetch(Bucket, "qiniu.png");
    if (ret.Code != (int)HttpCode.OK && !ret.Text.Contains("bucket source not set"))
        Console.WriteLine("prefetch error: " + ret.ToString());
    Console.WriteLine(ret.ToString());
    

    资源管理批量操作

    批量获取文件信息

    // 每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    string[] keys = {
        "00007.mp4",
        "0072102104.png"
    // 空间名
    string Bucket = "7qiniu";
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.StatOp(Bucket, key);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("{0}, {1}, {2}, {3}, {4}", info.Data.MimeType,
                info.Data.PutTime, info.Data.Hash, info.Data.Fsize, info.Data.FileType);
            Console.WriteLine(info.Data.Error);
    

    批量修改文件类型

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    // 空间名
    string Bucket = "7qiniu";
    // 文件名
    string[] keys = {
        "354",
        "3.json"
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.ChangeTypeOp(Bucket, key, 1);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("chtype success");
            Console.WriteLine(info.Data.Error);
    

    批量删除文件

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    // 设置空间
    string Bucket = "7qiniu";
    string[] keys = {
        "00_wo_ts_a.mp4",
        "0327-02.png",
        "0715589972949ea3a.mp4"
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.DeleteOp(Bucket, key);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("delete success");
            Console.WriteLine(info.Data.Error);
    

    批量复制文件

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    // 原空间
    string srcBucket = "7qiniu";
    // 目标空间
    string dstBucket = "07qiniu";
    string[] keys = {
        "007210021.png",
        "0072102104.png",
        "0327-02.png"
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.CopyOp(srcBucket, key, dstBucket, key, true);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("copy success");
            Console.WriteLine(info.Data.Error);
    

    批量移动或重命名文件

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    // 原空间
    string srcBucket = "7qiniu";
    // 目标空间
    string dstBucket = "01test";
    string[] keys = {
        "007210021.png",
        "0072102104.png"
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.MoveOp(srcBucket, key, dstBucket, key + "-batch-move", true);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("move success");
            Console.WriteLine(info.Data.Error);
    

    批量更新文件的有效期

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    string[] keys = {
        "4389.png",
        "4.gif"
    // 空间名
    string Bucket = "7qiniu";
    List<string> ops = new List<string>();
    foreach (string key in keys)
        string op = bucketManager.DeleteAfterDaysOp(Bucket, key, 7);
        ops.Add(op);
    BatchResult ret = bucketManager.Batch(ops);
    if (ret.Code / 100 != 2)
        Console.WriteLine("batch error: " + ret.ToString());
    foreach (BatchInfo info in ret.Result)
        if (info.Code == (int)HttpCode.OK)
            Console.WriteLine("deleteAfterDays success");
            Console.WriteLine(info.Data.Error + "2");
    

    批量更新文件存储类型

    //每个operations的数量不可以超过1000个,如果总数量超过1000,需要分批发送
    //type=0为普通存储,type=1为低频存储
    string[] keys = {
            "qiniu-0.png",
            "qiniu-1.png",
            "qiniu-2.png"
        List<string> ops = new List<string>();
        int type = 0;
        foreach (string key in keys)
            string op = bucketManager.ChangeTypeOp(Bucket, key, type);
            ops.Add(op);
        BatchResult ret = bucketManager.Batch(ops);
        if (ret.Code / 100 != 2)
            Console.WriteLine("batch error: " + ret.ToString());
        foreach (BatchInfo info in ret.Result)
            if (info.Code == (int)HttpCode.OK)
                Console.WriteLine("chtype success");
                Console.WriteLine(info.Data.Error);
    

    持久化数据处理

    发送数据处理请求(数据处理指令)

    对于已经保存到七牛空间的文件,可以通过发送持久化的数据处理指令来进行处理,这些指令支持七牛官方提供的指令,也包括客户自己开发的自定义数据处理的指令。数据处理的结果还可以通过七牛主动通知的方式告知业务服务器。

    闲时任务的功能介绍、使用场景、定价,详见 闲时任务策略说明

    Mac mac = new Mac(AccessKey, SecretKey);
    Config config = new Config();
    OperationManager manager = new OperationManager(mac, config);
    //处理指令集合
    string saveMp4Entry = Base64.UrlSafeBase64Encode(Bucket + ":avthumb_test_target.mp4");
    string saveJpgEntry = Base64.UrlSafeBase64Encode(Bucket + ":avthumb_test_target.jpg");
    string avthumbMp4Fop = "avthumb/mp4|saveas/" + saveMp4Entry;
    string vframeJpgFop = "vframe/jpg/offset/1|saveas/" + saveJpgEntry;
    string fops = string.Join(";", new string[] { avthumbMp4Fop, vframeJpgFop });
    // 私有隊列名
    string pipeline = "da";
    string notifyUrl = "http://api.example.com/qiniu/pfop/notify";
    // 存储空间名
    string Bucket = "7qiniu";
    // 文件名
    string key = "00007.mp4";
    // 当服务端发现 fops 指定的数据处理结果已经存在,那就认为已经处理成功,避免重复处理浪费资源。加上本字段并设为 1,则可强制执行数据处理并覆盖原结果。
    bool force = true;
    // 任务类型:0: 普通任务 1: 闲时任务(一旦指定闲时任务,就不能指定 pipeline)
    int persistentType = 0;
    PfopResult pfopRet = manager.Pfop(Bucket, key, fops, pipeline, notifyUrl, force, persistentType);
    if (pfopRet.Code != (int)HttpCode.OK)
        Console.WriteLine("pfop error: " + pfopRet.ToString());
    //持久化数据处理返回的是任务的persistentId,可以根据这个id查询处理状态
    Console.WriteLine(pfopRet.PersistentId);
    

    发送数据处理请求(工作流模版)

    也可以支持使用工作流模版替代数据处理指令。工作流模板是预先编排好的一系列媒体处理流程(如转码、截图、视频拼接等各类处理),登录 对象存储控制台 进行创建,详情参考工作流模板操作指南workflowTemplateId 对应工作流模板列表的名称字段

    Mac mac = new Mac(AccessKey, SecretKey);
    Config config = new Config();
    OperationManager manager = new OperationManager(mac, config);
    // 私有隊列名
    string pipeline = "da";
    string notifyUrl = "http://api.example.com/qiniu/pfop/notify";
    // 存储空间名
    string Bucket = "7qiniu";
    // 文件名
    string key = "00007.mp4";
    // 工作流模版
    string workflowTemplateId = "tempname";
    // 当服务端发现 workflowTemplateId 指定的数据处理结果已经存在,那就认为已经处理成功,避免重复处理浪费资源。加上本字段并设为 1,则可强制执行数据处理并覆盖原结果。
    bool force = true;
    // 任务类型:0: 普通任务 1: 闲时任务(一旦指定闲时任务,就不能指定 pipeline)
    int persistentType = 0;
    PfopResult pfopRet = manager.Pfop(Bucket, key, null, pipeline, notifyUrl, force, persistentType, workflowTemplateId);
    if (pfopRet.Code != (int)HttpCode.OK)
        Console.WriteLine("pfop error: " + pfopRet.ToString());
    //持久化数据处理返回的是任务的persistentId,可以根据这个id查询处理状态
    Console.WriteLine(pfopRet.PersistentId);
    

    查询数据处理请求状态

    由于数据处理是异步处理,可以根据发送处理请求时返回的 persistentId 去查询任务的处理进度,如果在设置了persistentNotifyUrl 的情况下,直接业务服务器等待处理结果通知即可,如果需要主动查询,可以采用如下代码中的:

    //持久化数据处理返回的是任务的persistentId
    string persistentId = "z0.59abf1eb45a2650c9954087d";
    Mac mac = new Mac(AccessKey, SecretKey);
    Config config = new Config();
    OperationManager manager = new OperationManager(mac, config);
    PrefopResult ret = manager.Prefop(persistentId);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine("prefop error: " + ret.ToString());
    Console.WriteLine(ret.ToString());
    

    CDN 相关功能

  • 文件预取操作
  • 获取域名流量
  • 获取域名带宽
  • 获取日志下载链接
  • 构建时间戳防盗链访问链接
  • 在使用 CDN 相关功能之前,需要构建CdnManager对象:

    Mac mac = new Mac(AccessKey, SecretKey);
    CdnManager manager = new CdnManager(mac);
    
    //URL 列表
    string Domain = "sq.qiniuts.com";
    string[] urls = {
        string.Format("http://{0}/images/1.png",Domain),
        string.Format("http://{0}/images/2.png",Domain)
    RefreshResult ret = manager.RefreshUrls(urls);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    Console.WriteLine(ret.Result.Code);
    Console.WriteLine(ret.Result.Error);
    Console.WriteLine(ret.Result.UrlQuotaDay);
    Console.WriteLine(ret.Result.UrlSurplusDay);
    Console.WriteLine(ret.Result.RequestId);
    if (ret.Result.InvalidUrls != null)
        foreach (string url in ret.Result.InvalidUrls)
            Console.WriteLine(url);
    
    string Domain = "sq.qiniuts.com";
    //DIR 列表
    string[] dirs = {
        string.Format("http://{0}/images1/",Domain),
        string.Format("http://{0}/images2/",Domain)
    //刷新目录,刷新目录需要联系七牛技术支持开通权限
    //单次请求链接不可以超过10个,如果超过,请分批发送请求
    RefreshResult ret = manager.RefreshDirs(dirs);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    Console.WriteLine(ret.Result.Code);
    Console.WriteLine(ret.Result.Error);
    Console.WriteLine(ret.Result.DirQuotaDay);
    Console.WriteLine(ret.Result.DirSurplusDay);
    Console.WriteLine(ret.Result.RequestId);
    if (ret.Result.InvalidDirs != null)
        foreach (string dir in ret.Result.InvalidDirs)
            Console.WriteLine(dir);
    
    //URL 列表
    string Domain = "sq.qiniuts.com";
    string[] urls = {
        string.Format("http://{0}/images/1.png",Domain),
        string.Format("http://{0}/images/2.png",Domain)
    PrefetchResult ret = manager.PrefetchUrls(urls);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    Console.WriteLine(ret.Result.Code);
    Console.WriteLine(ret.Result.Error);
    Console.WriteLine(ret.Result.QuotaDay);
    Console.WriteLine(ret.Result.SurplusDay);
    Console.WriteLine(ret.Result.RequestId);
    if (ret.Result.InvalidUrls != null)
        foreach (string url in ret.Result.InvalidUrls)
            Console.WriteLine(url);
    

    获取域名流量

    // 域名
    string Domain = "sq.qiniuts.com";
    string[] domains = new string[] { Domain };
    // 指定日期
    string start = "2017-08-01";
    string end = "2017-08-10";
    // 流量数据粒度
    string granu = "day";
    //获取域名流量
    FluxResult ret = manager.GetFluxData(domains, start, end, granu);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    foreach (string domain in domains)
        Console.WriteLine("flux data of domain: " + domain);
        foreach (string t in ret.Result.Time)
            Console.Write(t + "\t");
        Console.WriteLine();
        if (ret.Result.Data.ContainsKey(domain))
            if (ret.Result.Data[domain].China != null)
                Console.WriteLine("China:");
                foreach (UInt64 v in ret.Result.Data[domain].China)
                    Console.Write(v + "\t");
                Console.WriteLine();
            if (ret.Result.Data[domain].Oversea != null)
                Console.WriteLine("Oversea:");
                foreach (int v in ret.Result.Data[domain].Oversea)
                    Console.Write(v + "\t");
                Console.WriteLine();
    

    获取域名带宽

    // 域名
    string Domain = "sq.qiniuts.com";
    string[] domains = new string[] { Domain };
    // 设置时间范围
    string start = "2017-08-01";
    string end = "2017-08-10";
    // 带宽数据粒度
    string granu = "day";
    //获取域名带宽
    BandwidthResult ret = manager.GetBandwidthData(domains, start, end, granu);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    foreach (string domain in domains)
        Console.WriteLine("bandwidth data of domain: " + domain);
        foreach (string t in ret.Result.Time)
            Console.Write(t + "\t");
        Console.WriteLine();
        if (ret.Result.Data.ContainsKey(domain))
            if (ret.Result.Data[domain].China != null)
                Console.WriteLine("China:");
                foreach (int v in ret.Result.Data[domain].China)
                    Console.Write(v + "\t");
                Console.WriteLine();
            if (ret.Result.Data[domain].Oversea != null)
                Console.WriteLine("Oversea:");
                foreach (UInt64 v in ret.Result.Data[domain].Oversea)
                    Console.Write(v + "\t");
                Console.WriteLine();
    

    获取日志下载链接

    // 设置域名
    string Domain = "sq.qiniuts.com";
    // 设置时间
    string day = "2017-08-10";
    string[] domains = new string[] { Domain };
    LogListResult ret = manager.GetCdnLogList(domains, day);
    if (ret.Code != (int)HttpCode.OK)
        Console.WriteLine(ret.ToString());
    foreach (string domain in ret.Result.Data.Keys)
        Console.WriteLine("log list for domain: " + domain);
        foreach (LogData data in ret.Result.Data[domain])
            Console.WriteLine(data.Name + "\t" + data.Size + "\t" + data.Mtime + "\t" + data.Url);
    

    构建时间戳防盗链访问链接

    具体算法可以参考:时间戳防盗链

    string host = "http://qnls.example.com";
    string fileName = "hello/6000694.ls";
    string query = "v=34";
    int expireInSeconds = 3600;
    //加密密钥
    string encryptKey = "xxx";
    string finalUrl = CdnManager.CreateTimestampAntiLeechUrl(host, fileName, query, encryptKey, expireInSeconds);
    Console.WriteLine(finalUrl);
    

    API 参考

  • 存储 API 参考
  • 融合 CDN API 参考
  • 官方数据处理 API 参考
  • API 的使用,可以参考我们为大家精心准备的使用实例
  • 如果您有任何关于我们文档或产品的建议和想法,欢迎您通过以下方式与我们互动讨论:

  • 技术论坛 - 在这里您可以和其他开发者愉快的讨论如何更好的使用七牛云服务
  • 提交工单 - 如果您的问题不适合在论坛讨论或希望及时解决,您也可以提交一个工单,我们的技术支持人员会第一时间回复您
  • 博客 - 这里会持续更新发布市场活动和技术分享文章
  • 创建您的特性分支 git checkout -b my-new-feature

    提交您的改动 git commit -am ‘Added some feature’

    将您的修改记录提交到远程 git 仓库 git push origin my-new-feature

    然后到 github 网站的该 git 远程仓库的 my-new-feature 分支下发起 Pull Request

    基于 MIT 协议发布:

  • www.opensource.org/licenses/MIT
  •