• 关于

    对象存储 OSS只获取文件元信息

    的搜索结果

问题

OSS基本概念介绍

青衫无名 2019-12-01 21:35:42 1011 浏览量 回答数 0

问题

对象存储 OSS只获取文件元信息

2019-12-01 18:45:29 283 浏览量 回答数 1

问题

对象存储 OSS只获取文件元信息

2019-12-01 18:39:48 683 浏览量 回答数 1

阿里云爆款特惠专场,精选爆款产品低至0.95折!

爆款ECS云服务器8.1元/月起,云数据库低至1.5折,限时抢购!

问题

对象存储 OSS只获取文件元信息

2019-12-01 18:45:24 333 浏览量 回答数 1

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:16 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:16 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:17 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:16 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:17 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:16 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。 查看所有文件通过list来列出当前Bucket下的所有文件。主要的参数如下: prefix 指定只列出符合特定前缀的文件marker 指定只列出文件名大于marker之后的文件delimiter 用于获取文件的公共前缀max-keys 用于指定最多返回的文件个数 let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function list () { try { // 不带任何参数,默认最多返回1000个文件 let result = await client.list(); console.log(result); // 根据nextMarker继续列出文件 if (result.isTruncated) { let result = await client.list({ marker: result.nextMarker }); } // 列出前缀为'my-'的文件 let result = await client.list({ prefix: 'my-' }); console.log(result); // 列出前缀为'my-'且在'my-object'之后的文件 let result = await client.list({ prefix: 'my-', marker: 'my-object' }); console.log(result); } catch (e) { console.log(e); }}list(); 模拟目录结构OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。公共前缀的概念请参考列出Object。 假设Bucket中已有如下文件: foo/xfoo/yfoo/bar/afoo/bar/bfoo/hello/C/1foo/hello/C/2...foo/hello/C/9999接下来我们实现一个函数叫listDir,列出指定目录下的文件和子目录: let OSS = require('ali-oss');let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function listDir(dir) let result = await client.list({ prefix: dir, delimiter: '/' }); result.prefixes.forEach(function (subDir) { console.log('SubDir: %s', subDir); }); result.objects.forEach(function (obj) { console.log(Object: %s', obj.name); });end 运行结果如下: > await listDir('foo/')=> SubDir: foo/bar/ SubDir: foo/hello/ Object: foo/x Object: foo/y> await listDir('foo/bar/')=> Object: foo/bar/a Object: foo/bar/b> await listDir('foo/hello/C/')=> Object: foo/hello/C/1 Object: foo/hello/C/2 ... Object: foo/hello/C/9999文件元信息向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。因此元信息只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不能超过8KB。 使用put,putStream和multipartUpload时都可以通过指定meta参数来指定文件的元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function put () { try { let result = await client.put('object-key', 'local-file', { meta: { year: 2016, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}put(); 通过putMeta接口来更新文件元信息: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function putMeta () { try { let result = await client.putMeta('object-key', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }}putMeta(); 拷贝文件使用copy拷贝一个文件。拷贝可以发生在下面两种情况: 同一个Bucket两个不同Bucket,但是它们在同一个region,此时的源Object名字应为’/bucket/object’的形式 另外,拷贝时对文件元信息的处理有两种选择: 如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息如果指定了meta参数,则使用新的元信息覆盖源文件的信息 let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function copy () { try { // 两个Bucket之间拷贝 let result = await client.copy('to', '/from-bucket/from'); console.log(result); // 拷贝元信息 let result = await client.copy('to', 'from'); console.log(result); // 覆盖元信息 let result = await client.copy('to', 'from', { meta: { year: 2015, people: 'mary' } }); console.log(result); } catch (e) { console.log(e); }} 删除文件通过delete来删除某个文件: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function delete () { try { let result = yield client.delete('object-key'); console.log(result); } catch (e) { console.log(e); }}delete(); 批量删除文件通过deleteMulti来删除一批文件,用户可以通过quiet参数来指定是否返回删除的结果: let OSS = require('ali-oss')let client = new OSS({ region: '<Your region>', accessKeyId: '<Your AccessKeyId>', accessKeySecret: '<Your AccessKeySecret>', bucket: 'Your bucket name'});async function deleteMulti () { try { let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3']); console.log(result); let result = await client.deleteMulti(['obj-1', 'obj-2', 'obj-3'], { quiet: true }); console.log(result); } catch (e) { console.log(e); }}deleteMulti();

2019-12-01 23:14:17 0 浏览量 回答数 0

回答

本文介绍如何在本地文件网关控制台上完成共享设置。 前提条件 已注册阿里云账号,并完成实名认证,详情请参见阿里云账号注册流程。 说明 建议您使用RAM账户登录云存储网关控制台进行相关操作,详情请参见账号访问控制。 已开通云存储网关服务。 首次登录云存储网关控制台时,根据页面提示开通云存储网关服务。 已部署本地文件网关控制台,详情请参见部署本地文件网关控制台。 已创建OSS Bucket,详情请参见创建存储空间。 说明 云存储网关支持标准(Standard)类型、低频访问(IA)类型和归档存储类型的OSS Bucket。 对于归档文件,如果在创建共享时未开启归档支持功能,则在进行读操作时需要先手动解冻文件。 已添加磁盘,详情请参见添加磁盘。 步骤一:添加缓存 文件存储网关的每个共享目录都对应唯一一个缓存盘,创建多个共享目录则需要创建多个缓存盘。您可以将共享目录下的数据通过缓存盘传至阿里云OSS,也可以通过缓存盘将阿里云OSS数据同步到本地。 在浏览器中,输入https://<文件网关IP地址>访问本地文件网关控制台。 输入用户名和密码,单击确认。 选择缓存设置页面,单击创建。 在创建缓存对话框中,完成如下配置。 硬盘:单击选择,选择可用的硬盘。 在部署平台添加磁盘后,此处才有可用的硬盘,详情请参见添加磁盘。 文件系统:可选。勾选此选项,可重用该缓存盘中的数据。如果您误删共享后,可重建共享并使用缓存盘的数据重用功能进行数据恢复。 说明 如果缓存上没有文件系统,勾选重用选项,会创建缓存失败。 单击确认,完成添加。 步骤二:绑定云资源 创建以OSS Bucket为存储后端的共享资源,一个Bucket对应一个共享资源。文件存储网关支持创建多个云资源。 说明 通过客户端写入云存储网关的数据默认实时上传到OSS Bucket,也可在创建共享时设置延时上传,最大延时可支持设置为120s。 在本地文件网关控制台中,选择云资源设置页面,单击绑定。 在 绑定云资源对话框中,完成如下配置。 参数 说明 资源名称 设置云资源名称。 跨域绑定 选择是,可访问与文件网关不同地域的OSS Bucket。 选择否,只能访问与文件网关相同地域的Bucket。 说明 本地文件网关的时区必须与OSS Bucket的时区保持一致。 区域 选择Bucket所在区域。 Bucket名称 选择要绑定的Bucket。 使用SSL 如果选择是,可使用SSL访问OSS Bucket。 单击确认,完成云资源的绑定。 步骤三:创建共享 本地文件网关支持NFS共享和SMB共享,您可以根据需求进行选择。此处以创建NFS共享为例进行说明,如果您要创建SMB共享,详情请参见管理SMB共享。 安装NFS客户端,详情请参见安装NFS客户端。 返回本地文件网关控制台,选择NFS页面,单击创建。 在创建NFS对话框中,完成如下配置,并单击确认。 参数 说明 共享名称 NFS协议的虚拟挂载点。 NFSv4可以通过该名称直接挂载;NFSv3需要通过showmount -e <网关IP地址>获取挂载点。 读写客户端列表 允许读写访问NFS网关的IP地址或网段。 例如192.168.10.10或192.168.0.0/24,允许输入多个IP地址或者网段。 只读客户端列表 允许只读访问NFS网关的IP地址或网段。 例如192.168.10.10或192.168.0.0/24,允许输入多个IP地址或者网段。 用户映射 设置NFS客户端用户与NFS服务器用户之间的映射关系,仅当协议类型选择NFS时需要配置。 none:NFS客户端用户不被映射为NFS服务器的nobody用户。 root_squash:限制root用户,当NFS客户端以root用户身份访问时,映射为NFS服务器的nobody用户。 all_squash:限制所有用户,无论NFS客户端以何种用户身份访问,均映射为NFS服务器的nobody用户。 all_anonymous:限制所有用户,无论NFS客户端以何种用户身份访问,均映射为NFS服务器的匿名用户。 归档支持 选择是,开启归档支持功能。在已归档的文件上发起读操作请求时同步发起解冻请求,请求不会报错,但存在一定的时间延迟。 选择否,关闭归档支持功能。在已归档的文件上发起读操作请求时,需先手动解冻文件,否则请求会报错。 说明 基础型文件网关不支持归档支持功能。 启用 启用NFS共享。 如果您暂时不想使用该NFS共享,您可以选择否,关闭该NFS共享。 模式 包括缓存模式和复制模式。 复制模式:所有数据都会保存两份拷贝,一份保存在本地缓存,另一份保存在OSS。 缓存模式:本地缓存全量元数据和经常访问的用户数据。OSS侧保持全量数据。 反向同步 将OSS上的元数据同步回本地。适用于网关容灾和数据恢复/共享场景。 说明 反向同步会扫描Bucket下的所有对象,如果对象数量较多,会产生OSS API请求费用。具体费用,请参见对象存储 OSS 详细价格信息中的请求费用。 加密类型 包括不加密和服务端加密。 如果选择服务端加密,还需设置密钥ID。您可以在密钥管理服务控制台中创建密钥,详情请参见创建密钥。 开启OSS服务端加密后,允许用户自带密钥,目前支持从密钥管理服务中导入KMS密钥。 开启服务端加密后,通过共享目录上云的文件会在OSS端自动利用KMS密钥进行加密。您可以通过Get Object API验证当前文件是否已经加密,如果返回的Header中x-oss-server-side-encryption字段值为KMS,x-oss-server-side-encryption-key-id字段值为密钥ID,则表示已加密。 说明 白名单用户才能使用此功能。 在密钥管理服务控制台创建密钥时,需选择与OSS Bucket一样的区域。 Bucket名称 选择已创建的Bucket。 子目录 输入Bucket下的子目录。 子目录只支持英文和数字。 说明 从1.0.38版本开始支持将文件系统的根目录对接到OSS Bucket的某个子目录,便于用户做访问隔离。 子目录可以为OSS Bucket中已存在的目录也可以为OSS Bucket中还未创建的目录,创建共享完成后,将以该子目录为根目录,后续的文件和目录都会创建该目录下。 使用元数据盘 使用元数据盘后,将数据盘与元数据盘分离,元数据盘用于存放共享文件夹元数据信息。 选择是,需选择对应的元数据盘和数据盘。 选择否,需选择对应的缓存硬盘。 说明 白名单用户才能使用此功能。 忽略删除 文件删除操作不同步至OSS防止误操作。OSS侧保持全量数据。 同步延迟 设置同步延迟,在关闭文件会延迟一段时间再上传,防止频繁的本地修改操作造成OSS碎片。缺省值为5s,最大值120s。 最大写入速度 允许的最大写入速度为1280MB/s。默认为0,表示不限制速度。 最大上传速度 允许的最大上传速度为1280MB/s。默认为0,表示不限制速度。 说明 在限制速度的情况下,最大上传速度不能小于最大写入速度。 碎片优化 针对某些反复随机小IO读写的应用,启用此配置可提升性能,请根据场景谨慎选择。 上传优化 实时缓存回收,适用于数据纯备份上云场景。 单击确认,完成共享的创建。 创建完成后,您可以通过NFS客户端访问共享目录,详情请参见访问NFS共享目录。

1934890530796658 2020-03-31 11:11:08 0 浏览量 回答数 0

回答

本文介绍如何在本地文件网关控制台上完成共享设置。 前提条件 已注册阿里云账号,并完成实名认证,详情请参见阿里云账号注册流程。 说明 建议您使用RAM账户登录云存储网关控制台进行相关操作,详情请参见账号访问控制。 已开通云存储网关服务。 首次登录云存储网关控制台时,根据页面提示开通云存储网关服务。 已部署本地文件网关控制台,详情请参见部署本地文件网关控制台。 已创建OSS Bucket,详情请参见创建存储空间。 说明 云存储网关支持标准(Standard)类型、低频访问(IA)类型和归档存储类型的OSS Bucket。 对于归档文件,如果在创建共享时未开启归档支持功能,则在进行读操作时需要先手动解冻文件。 已添加磁盘,详情请参见添加磁盘。 步骤一:添加缓存 文件存储网关的每个共享目录都对应唯一一个缓存盘,创建多个共享目录则需要创建多个缓存盘。您可以将共享目录下的数据通过缓存盘传至阿里云OSS,也可以通过缓存盘将阿里云OSS数据同步到本地。 在浏览器中,输入https://<文件网关IP地址>访问本地文件网关控制台。 输入用户名和密码,单击确认。 选择缓存设置页面,单击创建。 在创建缓存对话框中,完成如下配置。 硬盘:单击选择,选择可用的硬盘。 在部署平台添加磁盘后,此处才有可用的硬盘,详情请参见添加磁盘。 文件系统:可选。勾选此选项,可重用该缓存盘中的数据。如果您误删共享后,可重建共享并使用缓存盘的数据重用功能进行数据恢复。 说明 如果缓存上没有文件系统,勾选重用选项,会创建缓存失败。 单击确认,完成添加。 步骤二:绑定云资源 创建以OSS Bucket为存储后端的共享资源,一个Bucket对应一个共享资源。文件存储网关支持创建多个云资源。 说明 通过客户端写入云存储网关的数据默认实时上传到OSS Bucket,也可在创建共享时设置延时上传,最大延时可支持设置为120s。 在本地文件网关控制台中,选择云资源设置页面,单击绑定。 在 绑定云资源对话框中,完成如下配置。 参数 说明 资源名称 设置云资源名称。 跨域绑定 选择是,可访问与文件网关不同地域的OSS Bucket。 选择否,只能访问与文件网关相同地域的Bucket。 说明 本地文件网关的时区必须与OSS Bucket的时区保持一致。 区域 选择Bucket所在区域。 Bucket名称 选择要绑定的Bucket。 使用SSL 如果选择是,可使用SSL访问OSS Bucket。 单击确认,完成云资源的绑定。 步骤三:创建共享 本地文件网关支持NFS共享和SMB共享,您可以根据需求进行选择。此处以创建NFS共享为例进行说明,如果您要创建SMB共享,详情请参见管理SMB共享。 安装NFS客户端,详情请参见安装NFS客户端。 返回本地文件网关控制台,选择NFS页面,单击创建。 在创建NFS对话框中,完成如下配置,并单击确认。 参数 说明 共享名称 NFS协议的虚拟挂载点。 NFSv4可以通过该名称直接挂载;NFSv3需要通过showmount -e <网关IP地址>获取挂载点。 读写客户端列表 允许读写访问NFS网关的IP地址或网段。 例如192.168.10.10或192.168.0.0/24,允许输入多个IP地址或者网段。 只读客户端列表 允许只读访问NFS网关的IP地址或网段。 例如192.168.10.10或192.168.0.0/24,允许输入多个IP地址或者网段。 用户映射 设置NFS客户端用户与NFS服务器用户之间的映射关系,仅当协议类型选择NFS时需要配置。 none:NFS客户端用户不被映射为NFS服务器的nobody用户。 root_squash:限制root用户,当NFS客户端以root用户身份访问时,映射为NFS服务器的nobody用户。 all_squash:限制所有用户,无论NFS客户端以何种用户身份访问,均映射为NFS服务器的nobody用户。 all_anonymous:限制所有用户,无论NFS客户端以何种用户身份访问,均映射为NFS服务器的匿名用户。 归档支持 选择是,开启归档支持功能。在已归档的文件上发起读操作请求时同步发起解冻请求,请求不会报错,但存在一定的时间延迟。 选择否,关闭归档支持功能。在已归档的文件上发起读操作请求时,需先手动解冻文件,否则请求会报错。 说明 基础型文件网关不支持归档支持功能。 启用 启用NFS共享。 如果您暂时不想使用该NFS共享,您可以选择否,关闭该NFS共享。 模式 包括缓存模式和复制模式。 复制模式:所有数据都会保存两份拷贝,一份保存在本地缓存,另一份保存在OSS。 缓存模式:本地缓存全量元数据和经常访问的用户数据。OSS侧保持全量数据。 反向同步 将OSS上的元数据同步回本地。适用于网关容灾和数据恢复/共享场景。 说明 反向同步会扫描Bucket下的所有对象,如果对象数量较多,会产生OSS API请求费用。具体费用,请参见对象存储 OSS 详细价格信息中的请求费用。 加密类型 包括不加密和服务端加密。 如果选择服务端加密,还需设置密钥ID。您可以在密钥管理服务控制台中创建密钥,详情请参见创建密钥。 开启OSS服务端加密后,允许用户自带密钥,目前支持从密钥管理服务中导入KMS密钥。 开启服务端加密后,通过共享目录上云的文件会在OSS端自动利用KMS密钥进行加密。您可以通过Get Object API验证当前文件是否已经加密,如果返回的Header中x-oss-server-side-encryption字段值为KMS,x-oss-server-side-encryption-key-id字段值为密钥ID,则表示已加密。 说明 白名单用户才能使用此功能。 在密钥管理服务控制台创建密钥时,需选择与OSS Bucket一样的区域。 Bucket名称 选择已创建的Bucket。 子目录 输入Bucket下的子目录。 子目录只支持英文和数字。 说明 从1.0.38版本开始支持将文件系统的根目录对接到OSS Bucket的某个子目录,便于用户做访问隔离。 子目录可以为OSS Bucket中已存在的目录也可以为OSS Bucket中还未创建的目录,创建共享完成后,将以该子目录为根目录,后续的文件和目录都会创建该目录下。 使用元数据盘 使用元数据盘后,将数据盘与元数据盘分离,元数据盘用于存放共享文件夹元数据信息。 选择是,需选择对应的元数据盘和数据盘。 选择否,需选择对应的缓存硬盘。 说明 白名单用户才能使用此功能。 忽略删除 文件删除操作不同步至OSS防止误操作。OSS侧保持全量数据。 同步延迟 设置同步延迟,在关闭文件会延迟一段时间再上传,防止频繁的本地修改操作造成OSS碎片。缺省值为5s,最大值120s。 最大写入速度 允许的最大写入速度为1280MB/s。默认为0,表示不限制速度。 最大上传速度 允许的最大上传速度为1280MB/s。默认为0,表示不限制速度。 说明 在限制速度的情况下,最大上传速度不能小于最大写入速度。 碎片优化 针对某些反复随机小IO读写的应用,启用此配置可提升性能,请根据场景谨慎选择。 上传优化 实时缓存回收,适用于数据纯备份上云场景。 单击确认,完成共享的创建。 创建完成后,您可以通过NFS客户端访问共享目录,详情请参见访问NFS共享目录。

1934890530796658 2020-03-31 11:11:37 0 浏览量 回答数 0

问题

Ruby-SDK之如何实现管理文件?

青衫无名 2019-12-01 21:46:37 1098 浏览量 回答数 0

问题

JavaScript-SDK之如何实现管理文件(一)?

青衫无名 2019-12-01 21:44:26 973 浏览量 回答数 0

问题

跨区域数据复制功能上线

terry.zhouh 2019-12-01 21:02:12 20675 浏览量 回答数 16

问题

OSS如何实现管理跨区域复制?

青衫无名 2019-12-01 21:37:01 2257 浏览量 回答数 0

回答

本文以部署在ECS实例上的Python访问OSS为例,详细介绍了如何借助ECS实例RAM角色,使实例内部的应用程序可以使用STS临时凭证访问其他云产品。 前提条件 已注册阿里云账号。如还未注册,请先完成账号注册。 已创建一个ECS实例,详情请参见使用向导创建实例。 背景信息 以往部署在ECS实例中的应用程序如果需要访问阿里云其他云产品,您通常需要借助AccessKeyID和AccessKeySecret(下文简称AK)来实现。AK是您访问阿里云API的密钥,具有相应账号的完整权限。为了方便应用程序对AK的管理,您通常需要将AK保存在应用程序的配置文件中或以其他方式保存在ECS实例中,这在一定程度上增加了AK管理的复杂性,并且降低了AK的保密性。甚至,如果您需要实现多地域一致性部署,AK会随着镜像以及使用镜像创建的实例扩散出去。这种情况下,当您需要更换AK时,您就需要逐台更新和重新部署实例和镜像。 现在借助于ECS实例RAM角色,您可以将RAM角色和ECS实例关联起来,实例内部的应用程序可以通过STS临时凭证访问其他云产品。其中STS临时凭证由系统自动生成和更新,应用程序可以使用指定的实例元数据URL获取STS临时凭证,无需特别管理。同时借助于RAM,通过对角色和授权策略的管理,您可以达到不同实例对不同云产品或相同云产品具有各自访问权限的目的。 说明 为了方便您随本文样例快速入门,文档里所有操作均在OpenAPI Explorer完成。OpenAPI Explorer通过已登录用户信息获取当前账号临时AK,对当前账号发起线上资源操作,请谨慎操作。创建实例操作会产生费用。操作完成后请及时释放实例。 操作步骤 为了使ECS借助实例RAM角色,实现内部Python可以使用STS临时凭证访问OSS,您需要完成以下步骤: 步骤一:创建RAM角色并配置授权策略 步骤二:指定RAM角色创建并设置ECS实例 步骤三:在实例内部访问实例元数据URL获取STS临时凭证 步骤四:基于临时凭证,使用Python SDK访问OSS 步骤一:创建RAM角色并配置授权策略 完成以下步骤,创建RAM角色并配置授权策略: 创建RAM角色。 找到OpenAPI Explorer RAM产品下CreateRole API。其中: RoleName:设置角色的名称。根据自己的需要填写,本示例中为 EcsRamRoleTest。 AssumeRolePolicyDocument: 填写如下内容,表示该角色为一个服务角色,受信云服务(本示例中为ECS)可以扮演该角色。 { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": [ "ecs.aliyuncs.com" ] } } ], "Version": "1" } 创建授权策略。 找到OpenAPI Explorer RAM产品下的CreatePolicy API。其中: PolicyName:设置授权策略的名称。本示例中为EcsRamRolePolicyTest。 PolicyDocument:输入授权策略内容。本示例中填写如下内容,表示该角色具有OSS只读权限。 { "Statement": [ { "Action": [ "oss:Get*", "oss:List*" ], "Effect": "Allow", "Resource": "*" } ], "Version": "1" } 为角色附加授权。找到OpenAPI Explorer RAM产品下的AttachPolicyToRole API。 PolicyType:填写Custom。 PolicyName:填写第2步创建的策略名称,如本示例中的EcsRamRolePolicyTest。 RoleName:填写第1步创建的角色名称,如本示例中的EcsRamRoleTest。 步骤二:指定RAM角色创建并设置ECS实例 您可以通过以下任一种方式为ECS实例指定RAM角色: 将实例RAM角色附加到一个已创建的ECS实例上 您可以使用ECS的AttachInstanceRamRole API附加实例RAM角色到已有的VPC类型ECS实例授权访问,设置信息如下: RegionId:为实例所在的地域ID。 RamRoleName:RAM角色的名称。本示例中为EcsRamRoleTest。 InstanceIds:需要附加实例RAM角色的VPC类型ECS实例ID。本示例中为["i-bXXXXXXXX"]。 指定RAM角色创建并设置ECS实例 按以下步骤指定RAM角色创建并设置ECS实例。 创建实例。 找到OpenAPI Explorer ECS产品下的CreateInstance API,根据实际情况填写请求参数。必须填写的参数包括: RegionId:实例所在地域。本示例中为cn-hangzhou。 ImageId:实例的镜像。本示例中为centos_7_03_64_40G_alibase_20170503.vhd。 InstanceType:实例的规格。本示例中为ecs.g6.large。 VSwitchId:实例所在的VPC虚拟交换机。因为ECS实例RAM角色目前只支持VPC类型ECS实例,所以VSwitchId是必需的。 RamRoleName:RAM角色的名称。本示例中为EcsRamRoleTest。 如果您希望授权子账号创建指定RAM角色的ECS实例,那么子账号除了拥有创建ECS实例的权限之外,还需要增加PassRole权限。所以,您需要创建一个如下所示的自定义授权策略并绑定到子账号上。 如果是创建ECS实例,[ECS RAM Action]可以是ecs:CreateInstance,您也可以根据实际情况添加更多的权限。 如果您需要为子账号授予所有ECS操作权限,[ECS RAM Action]应该替换为ecs:*。 说明 [ECS RAM Action]的取值详情请参见鉴权规则。 { "Statement": [ { "Action": "[ECS RAM Action]", "Resource": "*", "Effect": "Allow" }, { "Action": "ram:PassRole", "Resource": "*", "Effect": "Allow" } ], "Version": "1" } 设置密码并启动实例。 使用API或在控制台设置ECS实例能访问公网。 步骤三:在实例内部访问实例元数据URL获取STS临时凭证 完成以下步骤,获取实例的STS临时凭证: 说明 STS临时凭证失效前半小时会生成新的STS临时凭证,在这半小时内,新旧STS临时凭证均可使用。 远程连接ECS实例。连接方式请参见连接方式概述。 访问http://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTest获取STS临时凭证。路径最后一部分是RAM角色名称,您应替换为自己的创建的RAM角色名称。 说明 本示例中使用curl命令访问上述URL。如果您使用的是Windows ECS实例,请参见实例元数据。 示例输出结果如下。 [root@local ~]# curl http://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTest { "AccessKeyId" : "STS.J8XXXXXXXXXX4", "AccessKeySecret" : "9PjfXXXXXXXXXBf2XAW", "Expiration" : "2017-06-09T09:17:19Z", "SecurityToken" : "CAIXXXXXXXXXXXwmBkleCTkyI+", "LastUpdated" : "2017-06-09T03:17:18Z", "Code" : "Success" } 步骤四:基于临时凭证,使用Python SDK访问OSS 本示例中,我们基于STS临时凭证使用Python SDK列举实例所在地域的某个OSS存储空间(Bucket)里的10个文件。 前提条件: 您已经远程连接到ECS实例。 您的ECS实例已经安装了Python。如果您用的是Linux ECS实例,必须安装pip。 您在实例所在的地域已经创建了存储空间(Bucket),并已经获取Bucket的名称和Endpoint。本示例中,Bucket名称为ramroletest,Endpoint为oss-cn-hangzhou.aliyuncs.com。 完成以下步骤,使用Python SDK访问OSS: 运行命令pip install oss2,安装OSS Python SDK。 说明 如果您用的是Windows ECS实例,请参见 《对象存储 OSS SDK 参考》 的安装 Python SDK。 执行下述命令进行测试。 import oss2 from itertools import islice auth = oss2.StsAuth(<AccessKeyId>, <AccessKeySecret>, <SecurityToken>) bucket = oss2.Bucket(auth, <您的 Endpoint>, <您的 Bucket 名称>) for b in islice(oss2.ObjectIterator(bucket), 10): print(b.key) 其中: oss2.StsAuth中的3个参数分别对应于步骤三中返回的AccessKeyId、AccessKeySecret和SecurityToken。 oss2.Bucket中后2个参数是Bucket的名称和Endpoint。 示例输出结果如下。 [root@local ~]# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import oss2 >>> from itertools import islice >>> auth = oss2.StsAuth("STS.J8XXXXXXXXXX4", "9PjfXXXXXXXXXBf2XAW", "CAIXXXXXXXXXXXwmBkleCTkyI+") >>> bucket = oss2.Bucket(auth, "oss-cn-hangzhou.aliyuncs.com", "ramroletest") >>> for b in islice(oss2.ObjectIterator(bucket), 10): ... print(b.key) ... ramroletest.txt test.shh

1934890530796658 2020-03-25 18:42:34 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:07 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:07 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:08 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:07 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:07 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:06 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:08 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:08 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:08 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档OSS 移动端SDK 上传文件的方式可以分为:简单上传,追加上传,分片上传和断点续传。 简单上传上传Object可以直接上传OSSData,或者通过NSURL上传一个文件: OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 可选字段,可不设置put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject// put.contentType = @"";// put.contentMd5 = @"";// put.contentEncoding = @"";// put.contentDisposition = @"";// put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 可以在上传时设置元信息或者其他HTTP头部OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 上传到文件目录OSS服务是没有文件夹这个概念的,所有元素都是以文件来存储,但给用户提供了创建模拟文件夹的方式。创建模拟文件夹本质上来说是创建了一个名字以“/”结尾的文件,对于这个文件照样可以上传下载,只是控制台会对以“/”结尾的文件以文件夹的方式展示。 如,在上传文件是,如果把ObjectKey写为"folder/subfolder/file",即是模拟了把文件上传到folder/subfolder/下的file文件。注意,路径默认是”根目录”,不需要以’/‘开头。 上传时设置Content-Type和开启校验MD5上传时可以显式指定ContentType,如果没有指定,SDK会根据文件名或者上传的ObjectKey自动判断。另外,上传Object时如果设置了Content-Md5,那么OSS会用之检查消息内容是否与发送时一致。SDK提供了方便的Base64和MD5计算方法。 OSSPutObjectRequest * put = [OSSPutObjectRequest new];// 必填字段put.bucketName = @"<bucketName>";put.objectKey = @"<objectKey>";put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// put.uploadingData = <NSData *>; // 直接上传NSData// 设置Content-Type,可选put.contentType = @"application/octet-stream";// 设置MD5校验,可选put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // 如果是文件路径// put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // 如果是二进制数据// 进度设置,可选put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * putTask = [client putObject:put];[putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil;}];// [putTask waitUntilFinished];// [put cancel]; 追加上传Append Object以追加写的方式上传文件。通过Append Object操作创建的Object类型为Appendable Object,而通过Put Object上传的Object是Normal Object。 OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];// 必填字段append.bucketName = @"<bucketName>";append.objectKey = @"<objectKey>";append.appendPosition = 0; // 指定从何处进行追加NSString * docDir = [self getDocumentDirectory];append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];// 可选字段append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};// 以下可选字段的含义参考:https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject// append.contentType = @"";// append.contentMd5 = @"";// append.contentEncoding = @"";// append.contentDisposition = @"";OSSTask * appendTask = [client appendObject:append];[appendTask continueWithBlock:^id(OSSTask *task) { NSLog(@"objectKey: %@", append.objectKey); if (!task.error) { NSLog(@"append object success!"); OSSAppendObjectResult * result = task.result; NSString * etag = result.eTag; long nextPosition = result.xOssNextAppendPosition; } else { NSLog(@"append object failed, error: %@" , task.error); } return nil;}]; 上传后回调通知客户端在上传Object时可以指定OSS服务端在处理完上传请求后,通知您的业务服务器,在该服务器确认接收了该回调后将回调的结果返回给客户端。因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。 具体说明参考:Callback 代码示例: OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = @"<bucketName>";request.objectKey = @"<objectKey>";request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];// 设置回调参数request.callbackParam = @{ @"callbackUrl": @"<your server callback address>", @"callbackBody": @"<your callback body>" };// 设置自定义变量request.callbackVar = @{ @"<var1>": @"<value1>", @"<var2>": @"<value2>" };request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};OSSTask * task = [client putObject:request];[task continueWithBlock:^id(OSSTask *task) { if (task.error) { OSSLogError(@"%@", task.error); } else { OSSPutObjectResult * result = task.result; NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@", result.requestId, result.httpResponseHeaderFields, result.serverReturnJsonString); } return nil;}]; 分片上传因为篇幅的原因,分片上传参考:分片上传 断点续传 特别注意: 断点续传暂时只支持上传本地文件。 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。** 在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点上传功能。 在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。 断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理。 出于碎片管理的原因,如果在断点续传时取消当前任务。默认会同步清理已经上传到服务器的分片。如果取消时需要保留断点上传记录,需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。需要注意,如果本地保留记录时间过长,且Bucket设置lifeCycle规则定时清理了服务端分片。会出现服务端和移动端记录不一致的问题。 说明: 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。 在本地持久保存断点记录的调用方式(默认是不设置): OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = OSS_BUCKET_PRIVATE;//...NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];resumableUpload.recordDirectoryPath = cachesDir; 断点续传功能实现 // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];resumableUpload.bucketName = <bucketName>;resumableUpload.objectKey = <objectKey>;resumableUpload.partSize = 1024 * 1024;resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);};NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];//设置断点记录文件resumableUpload.recordDirectoryPath = cachesDir;//设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。resumableUpload.deleteUploadIdOnCancelling = NO;resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];OSSTask * resumeTask = [client resumableUpload:resumableUpload];[resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 该任务无法续传,需要获取新的uploadId重新上传 } } else { NSLog(@"Upload file success"); } return nil;}];// [resumeTask waitUntilFinished];// [resumableUpload cancel]; 数据完整性校验因为移动端网络环境的复杂性,OSS SDK提供了基于MD5和CRC64的端到端的数据完整性验证功能。 MD5校验 需要在上传文件时提供文件的Content-MD5值,OSS服务器会帮助用户进行MD5校验,只有在OSS服务器计算接收到的文件得到的MD5值和上传提供的MD5一致时才可以上传成功,从而保证上传数据的完整性。 OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = BUCKET_NAME;...request.contentMd5 = [OSSUtil fileMD5String:filepath]; CRC校验 与MD5相比,CRC64可以同时上传并计算CRC值。 // 构造上传请求OSSPutObjectRequest * request = [OSSPutObjectRequest new];request.bucketName = OSS_BUCKET_PRIVATE;///....request.crcFlag = OSSRequestCRCOpen;// 开启crc效验后。如果在传输中数据不一致,会提示OSSClientErrorCodeInvalidCRC 错误。OSSTask * task = [_client putObject:request];[[task continueWithBlock:^id(OSSTask *task) { //如果crc效验失败,会有error XCTAssertNil(task.error); return nil;}] waitUntilFinished];

2019-12-01 23:14:09 0 浏览量 回答数 0

回答

前言 随着计算机技术和 Internet 的日新月异,视频点播技术因其良好的人机交互性和流媒体传输技术倍受教育、娱乐等行业青睐,而在当前, 云计算平台厂商的产品线不断成熟完善, 如果想要搭建视频点播类应用,告别刀耕火种, 直接上云会扫清硬件采购、 技术等各种障碍,以阿里云为例: image 这是一个非常典型的解决方案, 对象存储 OSS 可以支持海量视频存储,采集上传的视频被转码以适配各种终端,CDN 加速终端设备播放视频的速度。此外还有一些内容安全审查需求, 比如鉴黄、鉴恐等。 而在视频点播解决方案中, 视频转码是最消耗计算力的一个子系统,虽然您可以使用云上专门的转码服务,但在很多情况下,您会选择自己搭建转码服务。比如: 您已经在虚拟机/容器平台上基于 FFmpeg 部署了一套视频处理服务,能否在此基础上让它更弹性,更高的可用性? 您有并发处理大量视频的需求。 您有很多超大的视频需要批量快速处理完, 比如每周五定期产生几百个 4G 以上的 1080P 大视频, 但是希望当天几个小时后全部处理完。 您有更高级的自定义处理需求,比如视频转码完成后, 需要记录转码详情到数据库, 或者在转码完成后, 自动将热度很高的视频预热到 CDN 上, 从而缓解源站压力。 自定义视频处理流程中可能会有多种操作组合, 比如转码、加水印和生成视频首页 GIF。后续为视频处理系统增加新需求,比如调整转码参数,希望新功能发布上线对在线服务无影响。 您的需求只是简单的转码需求,或是一些极其轻量的需求,比如获取 OSS 上视频前几帧的 GIF、获取视频或者音频的时长,自己搭建成本更低。 各种格式的音频转换或者各种采样率自定义、音频降噪等功能 您的视频源文件存放在 NAS 或者 ECS 云盘上,自建服务可以直接读取源文件处理,而不需要将它们再迁移到 OSS 上。 如果您的视频处理系统有上述需求,或者您期望实现一个 弹性、高可用、低成本、免运维、灵活支持任意处理逻辑 的视频处理系统,那么本文则是您期待的最佳实践方案。 Serverless 自定义音视频处理 在介绍具体方案之前, 先介绍两款产品: 函数计算 :阿里云函数计算是事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询、性能监控、报警等功能。 函数工作流:函数工作流(Function Flow,以下简称 FnF)是一个用来协调多个分布式任务执行的全托管云服务。您可以用顺序,分支,并行等方式来编排分布式任务,FnF 会按照设定好的步骤可靠地协调任务执行,跟踪每个任务的状态转换,并在必要时执行用户定义的重试逻辑,以确保工作流顺利完成。 免费开通函数计算,按量付费,函数计算有很大的免费额度。 免费开通函数工作流,按量付费,函数工作流有很大的免费额度。 函数计算可靠的执行任意逻辑, 逻辑可以是利用 FFmpeg 对视频任何处理操作, 也可以更新视频 meta 数据到数据库等。函数工作流对相应的函数进行编排, 比如第一步的函数是转码, 第二步的函数是转码成功后,将相应 meta 数据库写入数据库等。 至此,您应该初步理解了函数计算的自定义处理能力 + 函数工作流编排能力几乎满足您任何自定义处理的需求,接下来,本文以一个具体的示例展示基于函数计算和函数工作流打造的一个弹性高可用的 Serverless 视频处理系统,并与传统方案进行性能、成本和工程效率的对比。 Simple 视频处理系统 假设您是对视频进行单纯的处理, 架构方案图如下: image 如上图所示, 用户上传一个视频到 OSS, OSS 触发器自动触发函数执行, 函数调用 FFmpeg 进行视频转码, 并且将转码后的视频保存回 OSS。 OSS 事件触发器, 阿里云对象存储和函数计算无缝集成。您可以为各种类型的事件设置处理函数,当 OSS 系统捕获到指定类型的事件后,会自动调用函数处理。例如,您可以设置函数来处理 PutObject 事件,当您调用 OSS PutObject API 上传视频到 OSS 后,相关联的函数会自动触发来处理该视频。 Simple 视频处理系统示例工程地址 强大的监控系统: 您可以直接基于示例工程部署您的 Simple 音视频处理系统服务, 但是当您想要处理超大视频(比如 test_huge.mov ) 或者对小视频进行多种组合操作的时候, 您会发现函数会执行失败,原因是函数计算的执行环境有最大执行时间为 10 分钟的限制,如果最大的 10 分钟不能满足您的需求, 您可以选择: 对视频进行分片 -> 转码 -> 合成处理, 详情参考:fc-fnf-video-processing, 下文会详细介绍; 联系函数计算团队(钉钉群号: 11721331) 或者提工单: 适当放宽执行时长限制; 申请使用更高的函数内存 12G(8vCPU) 为了突破函数计算执行环境的限制(或者说加快大视频的转码速度), 进行各种复杂的组合操作, 此时引入函数工作流 FnF 去编排函数实现一个功能强大的视频处理工作流系统是一个很好的方案。 视频处理工作流系统 image 如上图所示, 假设用户上传一个 mov 格式的视频到 OSS,OSS 触发器自动触发函数执行, 函数调用 FnF,会同时进行 1 种或者多种格式的转码(由您触发的函数环境变量DST_FORMATS 参数控制)。 所以您可以实现如下需求: 一个视频文件可以同时被转码成各种格式以及其他各种自定义处理,比如增加水印处理或者在 after-process 更新信息到数据库等。 当有多个文件同时上传到 OSS,函数计算会自动伸缩, 并行处理多个文件, 同时每次文件转码成多种格式也是并行。 结合 NAS + 视频切片, 可以解决超大视频(大于 3G )的转码, 对于每一个视频,先进行切片处理,然后并行转码切片,最后合成,通过设置合理的切片时间,可以大大加速较大视频的转码速度。 所谓的视频切片,是将视频流按指定的时间间隔,切分成一系列分片文件,并生成一个索引文件记录分片文件的信息 视频处理工作流系统示例工程地址 示例效果: gif 函数计算 + 函数工作流 Serverless 方案 VS 传统方案 卓越的工程效率 自建服务 函数计算 + 函数工作流 Serverless 基础设施 需要用户采购和管理 无 开发效率 除了必要的业务逻辑开发,需要自己建立相同线上运行环境, 包括相关软件的安装、服务配置、安全更新等一系列问题 只需要专注业务逻辑的开发, 配合 FUN 工具一键资源编排和部署 并行&分布式视频处理 需要很强的开发能力和完善的监控系统来保证稳定性 通过 FnF 资源编排即可实现多个视频的并行处理以及单个大视频的分布式处理,稳定性和监控交由云平台 学习上手成本 除了编程语言开发能力和熟悉 FFmpeg 以外,可能使用 K8S 或弹性伸缩( ESS ),需要了解更多的产品、名词和参数的意义 会编写对应的语言的函数代码和熟悉 FFmpeg 使用即可 项目上线周期 在具体业务逻辑外耗费大量的时间和人力成本,保守估计大约 30 人天,包括硬件采购、软件和环境配置、系统开发、测试、监控报警、灰度发布系统等 预计 3 人天, 开发调试(2人天)+ 压测观察(1 人天) 弹性伸缩免运维,性能优异 自建服务 函数计算 + 函数工作流 Serverless 弹性高可用 需要自建负载均衡 (SLB),弹性伸缩,扩容缩容速度较 FC 慢 FC系统固有毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,免运维,视频处理工作流系统 (FnF + FC) 压测;性能优异, 详情见下面的转码性能表 监控报警查询 ECS 或者容器级别的 metrics 提供更细粒度的 FnF 流程执行以及函数执行情况, 同时可以查询每次函数执行的 latency 和日志等, 更加完善的报警监控机制 函数计算 + 函数工作流 Serverless 方案转码性能表 实验视频为是 89s 的 mov 文件 4K 视频: 4K.mov,云服务进行 mov -> mp4 普通转码需要消耗的时间为 188s, 将这个参考时间记为 T 视频切片时间 FC转码耗时 性能加速百分比 45s 160s 117.5% 25s 100s 188% 15s 70s 268.6% 10s 45s 417.8% 5s 35s 537.1% 性能加速百分比 = T / FC转码耗时 从上表可以看出,设置的视频切片时间越短, 视频转码时间越短, 函数计算可以自动瞬时调度出更多的计算资源来一起完成这个视频的转码, 转码性能优异。 更低的成本 具有明显波峰波谷的视频处理场景(比如只有部分时间段有视频处理请求,其他时间很少甚至没有视频处理请求),选择按需付费,只需为实际使用的计算资源付费。 没有明显波峰波谷的视频处理场景,可以使用预付费(包年包月),成本仍然具有竞争力。 函数计算成本优化最佳实践文档。 假设有一个基于 ECS 搭建的视频转码服务,由于是 CPU 密集型计算, 因此在这里将平均 CPU 利用率作为核心参考指标对评估成本,以一个月为周期,10 台 C5 ECS 的总计算力为例, 总的计算量约为 30% 场景下, 两个解决方案 CPU 资源利用率使用情况示意图大致如下: image 由上图预估出如下计费模型: 函数计算预付费 3CU 一个月: 246.27 元, 计算能力等价于 ECS 计算型 C5 ECS 计算型 C5 (2vCPU,4GB)+云盘: 包月219 元 函数计算按量付费占整个计算量的占比 <= 10%,费用约为 3×864×10% = 259.2 元,(3G 规格的函数满负载跑满一个月费用为:0.00011108×3×30×24×3600 = 863.8,详情查看计费) ITEM 平均CPU利用率 计算费用 总计 函数计算组合付费 >=80% 998(246.27×3+259.2) <= 998 按峰值预留ECS <=30% 2190(10*219) >=2190 在这个模型预估里面,可以看出 FC 方案具有很强的成本竞争力,在实际场景中, 基于 ECS 自建的视频转码服务 CPU 利用甚至很难达到 20%, 理由如下: 可能只有部分时间段有视频转码请求 为了用户体验,视频转码速度有一定的要求,可能一个视频转码就需要 10 台 ECS 并行处理来转码, 因此只能预备很多 ECS 因此,在实际场景中, FC 在视频处理上的成本竞争力远强于上述模型。 即使和云厂商视频转码服务单价 PK, 该方案仍有很强的成本竞争力 我们这边选用点播视频中最常用的两个格式(mp4、flv)之间进行相互转换,经实验验证, 函数内存设置为3G,基于该方案从 mp4 转码为 flv 的费用概览表: 实验视频为是 89s 的 mp4 和 flv 格式的文件视频, 测试视频地址: 480P.mp4 720P.mp4 1080P.mp4 4K.mp4 480P.flv 720P.flv 1080P.flv 4K.flv 测试命令: ffmpeg -i test.flv test.mp4 和 ffmpeg -i test.flv test.mp4 mp4 转 flv: 分辨率 bitrate 帧率 FC 转码耗费时间 FC 转码费用 某云视频处理费用 成本下降百分比 标清 640480 889 kb/s 24 11.2s 0.003732288 0.032 88.3% 高清 1280720 1963 kb/s 24 20.5s 0.00683142 0.065 89.5% 超清 19201080 3689 kb/s 24 40s 0.0133296 0.126 89.4% 4K 38402160 11185 kb/s 24 142s 0.04732008 0.556 91.5% flv 转 mp4: 分辨率 bitrate 帧率 FC 转码耗费时间 FC 转码费用 某云视频处理费用 成本下降百分比 标清 640480 712 kb/s 24 34.5s 0.01149678 0.032 64.1% 高清 1280720 1806 kb/s 24 100.3s 0.033424 0.065 48.6% 超清 19201080 3911 kb/s 24 226.4s 0.0754455 0.126 40.1% 4K 38402160 15109 kb/s 24 912s 0.30391488 0.556 45.3% 成本下降百分比 = (某云视频处理费用 - FC 转码费用)/ 云视频处理费用 某云视频处理,计费使用普通转码,转码时长不足一分钟,按照一分钟计算,这里计费采用的是 2 min,即使采用 1.5 min 计算, 成本下降百分比基本在10%以内浮动 从上表可以看出, 基于函数计算 + 函数工作流的方案在计算资源成本上对于计算复杂度较高的 flv 转 mp4 还是计算复杂度较低的 mp4 转 flv, 都具有很强的成本竞争力。 根据实际经验, 往往成本下降比上表列出来的更加明显, 理由如下: 测试视频的码率较高, 实际上很多场景绝大部分都是标清或者流畅视频的转码场景, 码率也比测试视频低,这个时候计算量变小, FC 执行时间短, 费用会降低, 但是通用的云转码服务计费是不变的. 很多视频分辨率在通用的云转码服务是计费是有很大损失的, 比如转码的视频是 856480 或者 1368768, 都会进入云转码服务的下一档计费单价, 比如856480 进入 1280720 高清转码计费档,1368768 进入 19201080 超清转码计费档, 单价基本是跨越式上升, 但是实际真正的计算量增加可能还不到30%, 而函数计算则是真正能做到按计算量付费. 操作部署 免费开通函数计算,按量付费,函数计算有很大的免费额度。 免费开通函数工作流,按量付费,函数工作流有很大的免费额度。 免费开通文件存储服务NAS, 按量付费 详情见各自示例工程的 README Simple 视频处理系统示例工程地址 视频处理工作流系统示例工程地址 总结 基于函数计算 FC 和函数工作流 FnF 的弹性高可用视频处理系统天然继承了这两个产品的优点: 无需采购和管理服务器等基础设施,只需专注视频处理业务逻辑的开发,大幅缩短项目交付时间和人力成本 提供日志查询、性能监控、报警等功能快速排查故障 以事件驱动的方式触发响应用户请求 免运维,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,性能优异 成本极具竞争力 相比于通用的转码处理服务: 超强自定义,对用户透明, 基于 FFmpeg 或者其他音视频处理工具命令快速开发相应的音视频处理逻辑 原有基于 FFmpeg 自建的音视频处理服务可以一键迁移 弹性更强, 可以保证有充足的计算资源为转码服务,比如每周五定期产生几百个 4G 以上的 1080P 大视频, 但是希望当天几个小时后全部处理完 各种格式的音频转换或者各种采样率自定义、音频降噪等功能, 比如专业音频处理工具 aacgain 和 mp3gain 可以和 serverless 工作流完成更加复杂、自定义的任务编排,比如视频转码完成后,记录转码详情到数据库,同时自动将热度很高的视频预热到 CDN 上, 从而缓解源站压力 更多的方式的事件驱动, 比如可以选择 OSS 自动触发(丰富的触发规则), 也可以根据业务选择 MNS 消息(支持 tag 过滤)触发 在大部分场景下具有很强的成本竞争力相比于其他自建服务: 毫秒级弹性伸缩,弹性能力超强,支持大规模资源调用,可弹性支持几万核.小时的计算力,比如 1 万节课半个小时完成转码 只需要专注业务逻辑代码即可,原生自带事件驱动模式,简化开发编程模型,同时可以达到消息(即音视频任务)处理的优先级,可大大提高开发运维效率 函数计算采用 3AZ 部署, 安全性高,计算资源也是多 AZ 获取, 能保证每个用户需要的算力峰值 开箱即用的监控系统, 如上面 gif 动图所示,可以多维度监控函数的执行情况,根据监控快速定位问题,同时给用户提供分析能力, 比如视频的格式分布, size 分布等 在大部分场景下具有很强的成本竞争力, 因为在函数计算是真正的按量付费(计费粒度在百毫秒), 可以理解为 CPU 的利用率为 100% 最后一一回答一下之前列出的问题: Q1: 您已经在虚拟机/容器平台上基于 FFmpeg 部署了一套视频处理服务,能否在此基础上让它更弹性,更高的可用性? A: 如工程示例所示,在虚拟机/容器平台上基于 FFmpeg 的服务可以轻松切换到函数计算, FFmpeg 相关命令可以直接移值到函数计算,改造成本较低, 同时天然继承了函数计算弹性高可用性特性。 Q2:您的需求只是简单的转码需求,或是一些极其轻量的需求,比如获取 OSS 上视频前几帧的 GIF 等。 自己搭建成本更低。 A: 函数计算天生就是解决这些自定义问题, 你的代码你做主, 代码中快速执行几个 FFmpeg 的命令即可完成需求。典型示例: fc-oss-ffmpeg Q3: 您有更高级的自定义处理需求,比如视频转码完成后, 需要记录转码详情到数据库, 或者在转码完成后, 自动将热度很高的视频预热到 CDN 上, 从而缓解源站压力。 A: 详情见视频处理工作流系统(函数计算 + 函数工作流方案),after-process 中可以做一些自定义的操作, 您还可以基于此流程再做一些额外处理等, 比如: 再增加后续流程 最开始增加 pre-process Q4: 您有并发同时处理大量视频的需求。 A: 详情见视频处理工作流系统(函数计算 + 函数工作流方案), 当有多个文件同时上传到 OSS, 函数计算会自动伸缩, 并行处理多个文件。详情可以参考 视频处理工作流系统 (FnF + FC) 压测 Q5:您有很多超大的视频需要批量快速处理完, 比如每周五定期产生几百个 4G 以上的 1080P 大视频, 但是希望当天几个小时后全部处理完。A: 详情可以参考视频处理工作流系统 (FnF + FC) 压测, 可以通过控制分片的大小, 可以使得每个大视频都有足够多的计算资源参与转码计算, 大大提高转码速度。 Q6: 自定义视频处理流程中可能会有多种操作组合, 比如转码、加水印和生成视频首页 GIF,后续为视频处理系统增加新需求,比如调整转码参数,希望新功能发布上线对在线服务无影响。 A: 详情见视频处理工作流系统(函数计算 + 函数工作流方案), FnF 只负责编排调用函数, 因此只需要更新相应的处理函数即可,同时函数有 version 和 alias 功能, 更好地控制灰度上线, 函数计算版本管理 Q7: 您的视频源文件存放在 NAS 或者 ECS 云盘上,自建服务可以直接读取源文件处理,而不需要将他们再迁移到 OSS 上。 A: 函数计算可以挂载 NAS, 直接对 NAS 中的文件进行处理

1934890530796658 2020-03-27 18:21:36 0 浏览量 回答数 0

问题

【精品问答】python技术1000问(1)

问问小秘 2019-12-01 21:57:48 454222 浏览量 回答数 19
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站