分享一次阿里云 nodejs oss sdk 判断文件是否存在
背景
给定路径判断oss是否存在该文件
开发
- 查看阿里云oss nodejs sdk文档 给出判断文件是否存在是如下代码
client.get(object).then((result) => {
if (result.res.status == 200) {
return true
}
}).catch((e)=> {
if (e.code == 'NoSuchKey') {
return false
}
})
从上可看出,其实它判断文件是去下载一个文件,很明显不适用于大文件。
- 查看阿里云oss java sdk文档 给出判断文件是否存在是如下代码
// 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,如果为true则忽略302重定向或镜像;如果
为false,则考虑302重定向或镜像。
boolean found = ossClient.doesObjectExist("<yourBucketName>", "<yourObjectName>");
此时我发现java给出了判断文件是否存在的api,但是Node并没有,我的想法是看java源码,看看其是用什么方法去判断的,最终找到如下代码:
public boolean doesObjectExist(GenericRequest genericRequest) throws OSSException, ClientException {
try {
this.getSimplifiedObjectMeta(genericRequest);
return true;
} catch (OSSException e) {
if (e.getErrorCode().equals(OSSErrorCode.NO_SUCH_BUCKET)
|| e.getErrorCode().equals(OSSErrorCode.NO_SUCH_KEY)) {
return false;
}
throw e;
}
}
/**
* Get simplified object meta.
*/
public SimplifiedObjectMeta getSimplifiedObjectMeta(GenericRequest genericRequest) {
}
从注释可以看出,它其实是去获取文件的meta信息来判断他是否存在的。
- 步骤2里的代码给我提供灵感,我可以写一个方法获取其文件的meta信息。在nodejs sdk 中发现有修改meta API 即 client.putMeta(name, meta[, options])(Set an exists object meta.),我借鉴其putMeta写一个getMeta方法。所以查看其源码发现其有head方法:
proto.head = async function head(name, options) {
const params = this._objectRequestParams('HEAD', name, options);
params.successStatuses = [200, 304];
const result = await this.request(params);
const data = {
meta: null,
res: result.res,
status: result.status
};
if (result.status === 200) {
Object.keys(result.headers).forEach((k) => {
if (k.indexOf('x-oss-meta-') === 0) {
if (!data.meta) {
data.meta = {};
}
data.meta[k.substring(11)] = result.headers[k];
}
});
}
return data;
};
// 看到github 给这个方法的备注是(Head an object and get the meta info.) 这个就是我要的方法,绕了一圈,找到了该方法
- 回头又看了一下get 方法的文档 Get an object from the bucket. parameters:
- name {String} object name store on OSS
- [file] {String|WriteStream} file path or WriteStream instance to store the content
If `file` is null or ignore this parameter, function will return info contains `content` property.
- [options] {Object} optional parameters
- [timeout] {Number} the operation timeout
- [process] {String} image process params, will send with `x-oss-process`
e.g.: `{process: 'image/resize,w_200'}`
- [headers] {Object} extra headers, detail see [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616.html)
- 'Range' get specifying range bytes content, e.g.: `Range: bytes=0-9`
- 'If-Modified-Since' object modified after this time will return 200 and object meta,
otherwise return 304 not modified
- 'If-Unmodified-Since' object modified before this time will return 200 and object meta,
otherwise throw PreconditionFailedError
- 'If-Match' object etag equal this will return 200 and object meta,
otherwise throw PreconditionFailedError
- 'If-None-Match' object etag not equal this will return 200 and object meta,
otherwise return 304 not modified
发现其也可以 给header 传Range参数,来判断文件是否存在, 也许官网上是想让我们调用get方法传range参数吧
结尾
虽然绕了一圈找到了解决的方法,但是还是希望能够仔细阅读文档吧,也希望阿里的文档越来越好吧,不用绕弯。