edit-icon download-icon

オブジェクトをアップロードする

最終更新日: Feb 14, 2018

OSS モバイル SDK は、単純アップロード、コンテンツ追加アップロード、マルチパートアップロード、および再開可能アップロードのいずれかの方法でファイルをアップロードします。

シンプルモードでローカルファイルをアップロードする

同期 API を呼び出してローカルファイルをアップロード:

  1. // Construct an upload request
  2. PutObjectRequest put = new PutObjectRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
  3. // Configure file metadata (optional)
  4. // ObjectMetadata metadata = new ObjectMetadata();
  5. // metadata.setContentType("application/octet-stream"); // Set the Content-Type
  6. // metadata.setContentMD5(BinaryUtil.calculateBase64Md5(uploadFilePath)); // Verify the MD5
  7. // put.setMetadata(metadata);
  8. try {
  9. PutObjectResult putResult = oss.putObject(put);
  10. Log.d("PutObject", "UploadSuccess");
  11. Log.d("ETag", putResult.getETag());
  12. Log.d("RequestId", putResult.getRequestId());
  13. } catch (ClientException e) {
  14. // Local exception, such as a network exception
  15. e.printStackTrace();
  16. } catch (ServiceException e) {
  17. // Service exception
  18. Log.e("RequestId", e.getRequestId());
  19. Log.e("ErrorCode", e.getErrorCode());
  20. Log.e("HostId", e.getHostId());
  21. Log.e("RawMessage", e.getRawMessage());
  22. }

注意: Android では、同期 API はサブスレッドでのみ呼び出すことができます。同期 API が UI スレッドで呼び出された場合は例外が発生します。UI スレッドでファイルをアップロードする必要がある場合は、非同期 API を使用します。

非同期 API を呼び出すことによってローカルファイルをアップロード:

  1. // Construct an upload request
  2. PutObjectRequest put = new PutObjectRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
  3. // You can set progress callback during the asynchronous upload
  4. put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
  5. @Override
  6. public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
  7. Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
  8. }
  9. });
  10. OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
  11. @Override
  12. public void onSuccess(PutObjectRequest request, PutObjectResult result) {
  13. Log.d("PutObject", "UploadSuccess");
  14. Log.d("ETag", result.getETag());
  15. Log.d("RequestId", result.getRequestId());
  16. }
  17. @Override
  18. public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
  19. // Request exception
  20. if (clientExcepion != null) {
  21. // Local exception, such as a network exception
  22. clientExcepion.printStackTrace();
  23. }
  24. if (serviceException != null) {
  25. // Service exception
  26. Log.e("ErrorCode", serviceException.getErrorCode());
  27. Log.e("RequestId", serviceException.getRequestId());
  28. Log.e("HostId", serviceException.getHostId());
  29. Log.e("RawMessage", serviceException.getRawMessage());
  30. }
  31. }
  32. });
  33. // task.cancel(); // You can cancel the task
  34. // task.waitUntilFinished(); // Wait until the task is complete

バイナリバイト[]配列を単純モードでアップロードする

  1. byte[] uploadData = new byte[100 * 1024];
  2. new Random().nextBytes(uploadData);
  3. // Construct an upload request
  4. PutObjectRequest put = new PutObjectRequest(testBucket, testObject, uploadData);
  5. try {
  6. PutObjectResult putResult = oss.putObject(put);
  7. Log.d("PutObject", "UploadSuccess");
  8. Log.d("ETag", putResult.getETag());
  9. Log.d("RequestId", putResult.getRequestId());
  10. } catch (ClientException e) {
  11. // Local exception, such as a network exception
  12. e.printStackTrace();
  13. } catch (ServiceException e) {
  14. // Service exception
  15. Log.e("RequestId", e.getRequestId());
  16. Log.e("ErrorCode", e.getErrorCode());
  17. Log.e("HostId", e.getHostId());
  18. Log.e("RawMessage", e.getRawMessage());
  19. }

ファイルをディレクトリにアップロードする

OSS はフォルダを使用しません。すべての要素はファイルとして保存されます。ただし、シミュレートされたフォルダを作成するためのモードが用意されています。シミュレートされたフォルダを作成すると、実際に名前にスラッシュ(/)が付いたファイルが作成されます。このファイルは通常のファイルとしてアップロードおよびダウンロードできますが、名前がスラッシュ(/)で終わるファイルは OSS コンソールにフォルダとして表示されます。

ファイルをアップロードするときに、ObjectKeyを"folder/subfolder/file"として書くと、そのファイルをfolder/subfolder/の下のfileオブジェクトにアップロードすることをシミュレートします。

注意: デフォルトの OSS パスは「ルートディレクトリ」であり、スラッシュ(/)で始める必要はありません。

アップロードされたファイルの Content-Type を設定する

Web サービスでは、Content-Type はファイルのタイプを定義し、ファイルの読み込みに使用されるモードとエンコーディングを決定します。場合によっては、アップロードするファイルの Content-Type を設定する必要があります。そうでなければ、ファイルは期待されたモードと符号化で読み取ることができません。OSS Android SDK を使用して Content-Type を設定せずにファイルをアップロードすると、SDK は Content-Type を自動的にファイル名の接尾辞に従って追加します。

  1. // Construct an upload request
  2. PutObjectRequest put = new PutObjectRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
  3. ObjectMetadata metadata = new ObjectMetadata();
  4. // Specify the Content-Type
  5. metadata.setContentType("application/octet-stream");
  6. // User-defined metadata
  7. metadata.addUserMetadata("x-oss-meta-name1", "value1");
  8. put.setMetadata(metadata);
  9. OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
  10. ...
  11. });

AppendObject

Append Object は、追加モードでファイルをアップロードするために使用されます。オブジェクトの追加で作成されたオブジェクトのタイプは Appendable Object で、Put Object でアップロードされたオブジェクトのタイプは Normal Object です。

  1. AppendObjectRequest append = new AppendObjectRequest(testBucket, testObject, uploadFilePath);
  2. ObjectMetadata metadata = new ObjectMetadata();
  3. metadata.setContentType("application/octet-stream");
  4. append.setMetadata(metadata);
  5. // Set the position for appending
  6. append.setPosition(0);
  7. append.setProgressCallback(new OSSProgressCallback<AppendObjectRequest>() {
  8. @Override
  9. public void onProgress(AppendObjectRequest request, long currentSize, long totalSize) {
  10. Log.d("AppendObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
  11. }
  12. });
  13. OSSAsyncTask task = oss.asyncAppendObject(append, new OSSCompletedCallback<AppendObjectRequest, AppendObjectResult>() {
  14. @Override
  15. public void onSuccess(AppendObjectRequest request, AppendObjectResult result) {
  16. Log.d("AppendObject", "AppendSuccess");
  17. Log.d("NextPosition", "" + result.getNextPosition());
  18. }
  19. @Override
  20. public void onFailure(AppendObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
  21. // Exception handling
  22. }
  23. });

[アップロードの追加]メソッドを使用するには、[位置]パラメータを正しく設定する必要があります。

  • 追加可能オブジェクトを作成すると、追加する位置は 0 になります。

  • Appendable Object にコンテンツを追加するには、追加する位置がオブジェクトの現在の長さになります。次の方法を使用して、オブジェクトの長さを取得できます。

    • append uploadの返された内容から長さを取得します。
    • head objectを使用して長さを取得します。

アップロード後のコールバック通知

クライアントにオブジェクトをアップロードするときに、OSS サーバーを構成して、アップロード要求が正常に処理されたことをビジネスサーバーに通知できます。サーバーはコールバックを受信すると、コールバックの結果をクライアントに返します。シンプルアップロードと比較して、コールバック通知を伴うアップロードでは、クライアントはコールバック要求と応答を処理するのに長い時間を要します。

詳細については、コールバックを参照してください。

サンプルコード:

  1. PutObjectRequest put = new PutObjectRequest(testBucket, testObject, uploadFilePath);
  2. put.setCallbackParam(new HashMap<String, String>() {
  3. {
  4. put("callbackUrl", "110.75.82.106/callback");
  5. put("callbackHost", "oss-cn-hangzhou.aliyuncs.com");
  6. put("callbackBodyType", "application/json");
  7. put("callbackBody", "{\"mimeType\":${mimeType},\"size\":${size}}");
  8. }
  9. });
  10. OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
  11. @Override
  12. public void onSuccess(PutObjectRequest request, PutObjectResult result) {
  13. Log.d("PutObject", "UploadSuccess");
  14. // This value is not empty only when the "Server Callback" is specified.
  15. String serverCallbackReturnJson = result.getServerCallbackReturnBody();
  16. Log.d("servercallback", serverCallbackReturnJson);
  17. }
  18. @Override
  19. public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
  20. // Exception handling
  21. }
  22. });

カスタムパラメータをサポートするには、次の設定が必要です。

  1. put.setCallbackParam(new HashMap<String, String>() {
  2. {
  3. put("callbackUrl", "http://182.92.192.125/leibin/notify.php");
  4. put("callbackHost", "oss-cn-hangzhou.aliyuncs.com");
  5. put("callbackBodyType", "application/json");
  6. put("callbackBody", "{\"object\":${object},\"size\":${size},\"my_var1\":${x:var1},\"my_var2\":${x:var2}}");
  7. }
  8. });
  9. put.setCallbackVars(new HashMap<String, String>() {
  10. {
  11. put("x:var1", "value1");
  12. put("x:var2", "value2");
  13. }
  14. });

マルチパートアップロード

スペースが限られているため、マルチパートアップロードの詳細については、マルチパートアップロードを参照してください。

再開可能なアップロード

注意:

  • 現在、この機能はローカルファイルのアップロードのみをサポートしています。

  • 再開可能なアップロードは、モバイルデバイスから小型ファイルと中型ファイルをアップロードする場合にはお勧めできません。再開可能なアップロードはマルチファイルアップロード方式を採用しています。これにより、1 つのファイルをアップロードするための複数のネットワーク要求が開始され、アップロードの効率が低下します。

ワイヤレスネットワーク接続では、通常、大きなファイルをアップロードするのに比較的長い時間がかかります。ネットワーク接続やネットワークの切り替えが不十分なため、アップロードが失敗することがあります。この場合、ファイル全体を再度アップロードする必要があります。この問題に対処するために、SDK は再開可能なアップロード機能を提供します。

アップロードする前に、再開可能なアップロードレコードを格納するフォルダを指定できます。フォルダを指定しないと、再開可能なアップロードは現在のアップロードタスクに対してのみ有効になります。ネットワーク上の問題により大きなファイルの一部がアップロードされない場合、ファイル全体ではなく、この部分のみが再度アップロードされるため、時間が節約され、トラフィックの消費が削減されます。フォルダを指定した場合、以前に失敗したアップロードタスクを再起動して、以前と同じバケット格納されたオブジェクトに同じファイルをアップロードすると、再開可能なアップロードレコードで指定されたコンテンツからアップロードが開始されます。

再開可能なアップロードタスクが失敗し、長時間再開しないと、アップロードされたパーツは OSS 上で無駄な部分になることがあります。この場合、バケットがタイムリーに部品をクリアするためのライフサイクルルールを設定することができます。ライフサイクル管理を参照してください。

注意:

  • 再開可能なアップロードは InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUploadに依存します。STS 認証モードを使用する場合は、API の使用に必要なアクセス許可を追加します。

  • 再開可能アップロードは、前回の通常のアップロードコールバック通知と同じ使用法で、アップロード後のコールバック通知をサポートします。

  • 再開可能なアップロードにより、各パーツのアップロード中にデフォルトで MD5 検証が有効になりました。要求にContent-Md5ヘッダーを再度設定する必要はありません。

次のコードでは、再開可能なアップロードレコードがローカルデバイスに永続的に保存されない呼び出しメソッドを使用しています。

  1. // Create a resumable upload request
  2. ResumableUploadRequest request = new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
  3. // Set the callback during the uploading process
  4. request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
  5. @Override
  6. public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
  7. Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
  8. }
  9. });
  10. // Asynchronous calls of the resumable upload
  11. OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
  12. @Override
  13. public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
  14. Log.d("resumableUpload", "success!");
  15. }
  16. @Override
  17. public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
  18. // Exception handling
  19. }
  20. });
  21. // resumableTask.waitUntilFinished(); // Wait until the task is complete

次のコードでは、再開可能なアップロードレコードがローカルデバイスに永続的に保存される呼び出しメソッドを使用しています。

  1. String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
  2. File recordDir = new File(recordDirectory);
  3. // The directory must exist. Otherwise, it will be automatically created.
  4. if (!recordDir.exists()) {
  5. recordDir.mkdirs();
  6. }
  7. // Create a resumable upload request with a parameter indicating the absolute path of the folder for storing resumable upload records
  8. ResumableUploadRequest request = new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>", recordDirectory);
  9. // Set the callback during the uploading process
  10. request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
  11. @Override
  12. public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
  13. Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
  14. }
  15. });
  16. OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
  17. @Override
  18. public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
  19. Log.d("resumableUpload", "success!");
  20. }
  21. @Override
  22. public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
  23. // Exception handling
  24. }
  25. });
  26. // resumableTask.waitUntilFinished();

再開可能なアップロードの実装:

  1. //Whether to delete the settings of resumable upload records when the OSSAsyncTask cancel() is called
  2. String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
  3. File recordDir = new File(recordDirectory);
  4. // The directory must exist. Otherwise, it will be automatically created.
  5. if (!recordDir.exists()) {
  6. recordDir.mkdirs();
  7. }
  8. // Create a resumable upload request with a parameter indicating the absolute path of the folder for storing resumable upload records
  9. ResumableUploadRequest request = new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>", recordDirectory);
  10. //If it is set as false, during the cancellation,the resumable upload records are not deleted. If you do not configure it and the default value is true, the resumable upload records are deleted and the files are uploaded again during the next upload.
  11. request.setDeleteUploadOnCancelling(false);
  12. // Set the callback during the uploading process
  13. request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
  14. @Override
  15. public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
  16. Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
  17. }
  18. });
  19. OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
  20. @Override
  21. public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
  22. Log.d("resumableUpload", "success!");
  23. }
  24. @Override
  25. public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
  26. // Exception handling
  27. }
  28. });
  29. // resumableTask.waitUntilFinished();

データ完全性検証

OSS SDK は、MD5 および CRC64 に基づいたエンドツーエンドのデータ整合性検証機能を提供し、モバイルネットワーク環境の複雑さを処理します。

MD5 検証

アップロード中にファイルに Content-MD5 値を指定する必要があります。次に、OSS サーバーは MD5 検証を実行します。アップロードは、OSS サーバによって受信されたファイルの MD5 値がアップロード中に提供された MD5 値と等しい場合にのみ成功することができ、アップロードされたデータの完全性が保証されます。

  1. OSSPutObjectRequest * request = [OSSPutObjectRequest new];
  2. request.bucketName = BUCKET_NAME;
  3. ...
  4. request.contentMd5 = [OSSUtil fileMD5String:filepath];

CRC 検証

MD5 と比較して、CRC64 はファイルのアップロード中に CRC 値を計算できます。

  1. // Construct an upload request
  2. OSSPutObjectRequest * request = [OSSPutObjectRequest new];
  3. request.bucketName = OSS_BUCKET_PRIVATE;
  4. ///....
  5. request.crcFlag = OSSRequestCRCOpen;
  6. // Enable CRC verification If the data is inconsistent during transmission, OSSClientErrorCodeInvalidCRC is thrown.
  7. OSSTask * task = [_client putObject:request];
  8. [[task continueWithBlock:^id(OSSTask *task) {
  9. // If CRC verification fails, an error is reported
  10. XCTAssertNil(task.error);
  11. return nil;
  12. }] waitUntilFinished];