1. 程式人生 > >Android阿里雲OSS多檔案同步上傳和刪除方案

Android阿里雲OSS多檔案同步上傳和刪除方案

上個專案中使用的是阿里雲OSS,查閱了官方文件,發現居然沒有多檔案上傳相關說明文件,只有一個單檔案非同步上傳的說明。既沒有多檔案上傳,又沒有同步上傳,刪除檔案亦然,凌亂。想到之前做過的七牛雲開發,決定用java遞迴的方式實現多檔案同步上傳和刪除,遞迴有風險,使用需謹慎哈。

阿里雲的配置和初始化官方已經說的很明白了,那麼這裡就直接了當說關鍵的:

一般來說我們都是獲得多檔案對應的本地地址List集合,然後遞迴每個url進行上傳 ---->

	/**
	 * 上傳多檔案
	 * 
	 * @param urls
	 */
	public void uploadFiles(List<String> urls) {
		if (null == urls || urls.size() == 0) {
			return;
		} // 上傳檔案
		ossUpload(urls);
	}


下面是阿里雲上傳遞迴體----->

        /**
	 * 阿里雲OSS上傳(預設是非同步多檔案上傳)
	 * @param urls
	 */
	private void ossUpload(final List<String> urls) {

		if (urls.size() <= 0) {
			// 檔案全部上傳完畢,這裡編寫上傳結束的邏輯,如果要在主執行緒操作,最好用Handler或runOnUiThead做對應邏輯
			return;// 這個return必須有,否則下面報越界異常,原因自己思考下哈
		}
		final String url = urls.get(0);
		if (TextUtils.isEmpty(url)) {
			urls.remove(0);
			// url為空就沒必要上傳了,這裡做的是跳過它繼續上傳的邏輯。
			ossUpload(urls);
			return;
		}

		File file = new File(url);
		if (null == file || !file.exists()) {
			urls.remove(0);
			// 檔案為空或不存在就沒必要上傳了,這裡做的是跳過它繼續上傳的邏輯。
			ossUpload(urls);
			return;
		}
		// 檔案字尾
		String fileSuffix = "";
		if (file.isFile()) {
			// 獲取檔案字尾名
			fileSuffix = file.getName().substring(file.getName().lastIndexOf("."));
		}
		// 檔案識別符號objectKey
		final String objectKey = "alioss_" + System.currentTimeMillis() + fileSuffix;
		// 下面3個引數依次為bucket名,ObjectKey名,上傳檔案路徑
		PutObjectRequest put = new PutObjectRequest(Constant.BUCKET_NAME, objectKey, url);

		// 設定進度回撥
		put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
			@Override
			public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
				// 進度邏輯
			}
		});
		// 非同步上傳
		OSSAsyncTask task = MyApp.getOSS().asyncPutObject(put,
				new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
					@Override
					public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上傳成功
						urls.remove(0);
						ossUpload(urls);// 遞迴同步效果
					}

					@Override
					public void onFailure(PutObjectRequest request, ClientException clientExcepion,
							ServiceException serviceException) { // 上傳失敗

						// 請求異常
						if (clientExcepion != null) {
							// 本地異常如網路異常等
							clientExcepion.printStackTrace();
						}
						if (serviceException != null) {
							// 服務異常
							Log.e("ErrorCode", serviceException.getErrorCode());
							Log.e("RequestId", serviceException.getRequestId());
							Log.e("HostId", serviceException.getHostId());
							Log.e("RawMessage", serviceException.getRawMessage());
						}
					}
				});
		// task.cancel(); // 可以取消任務
		// task.waitUntilFinished(); // 可以等待直到任務完成
	}

OK,看懂了沒,還是蠻簡單的,程式碼註釋的也很詳細。多檔案同步刪除與上述上傳邏輯屬於同一個套路,改幾個單詞差不多就可以了。這裡提醒下,阿里雲oss是根據objectKey刪除檔案的,所以判斷檔案存不存在是使用官方的程式碼判斷 :

boolean isExist = MyApp.getOSS().doesObjectExist(Constant.BUCKET_NAME, objectKey);

這次就不上傳原始碼了,大家有什麼疑問之處或需要原始碼可以直接回復我。

  2017年8月3日更新:  

         很多朋友都在問我一個請求能不能同時上傳多張圖片,我這邊可能因為沒有深入地研究官方文件,不能給大家作出肯定的回覆。

         But,個人認為沒有必要提供這樣的介面:首先,多圖片一個請求同時上傳需要消耗更多的CPU和記憶體資源(容易造成OOM);其次,漫長時間的網路連線,如果中間出現錯誤(網路,APP,系統出現問題)不僅前功盡棄,服務端還要刪除這些tmp檔案。
方案有沒有?
這裡提供簡單的方案思路(基於本文上傳方案的修改):
上文提到一個圖片上傳成功後會回撥OSSCompletedCallback的onSuccess方法,那麼我們可以在此記錄被上傳的圖片的objectKey於List或Map中,上傳結束後把這些objectKey集合通過一個請求反饋給App的服務端就可以了。

Excause Me?! 嗯!就這樣!