分享一次阿里云 nodejs oss sdk 判断文件是否存在
发布于 4 小时前 作者 luanxuechao 77 次浏览 最后一次编辑是 3 小时前 来自 分享

背景

给定路径判断oss是否存在该文件

开发

  1. 查看阿里云oss nodejs sdk文档 给出判断文件是否存在是如下代码
	   client.get(object).then((result) => {
			if (result.res.status == 200) {
			  return true
			}
		}).catch((e)=> {
		  if (e.code == 'NoSuchKey') {
			return false
		  }
		})

从上可看出,其实它判断文件是去下载一个文件,很明显不适用于大文件。

  1. 查看阿里云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信息来判断他是否存在的。

  1. 步骤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.) 这个就是我要的方法,绕了一圈,找到了该方法
  1. 回头又看了一下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参数吧

结尾

虽然绕了一圈找到了解决的方法,但是还是希望能够仔细阅读文档吧,也希望阿里的文档越来越好吧,不用绕弯。

回到顶部