使用 TransferManager 为了Amazon S3操作 - AWS SDK for Java

这些区域有:AWS SDK for Java团队正在招聘软件开发工程师那些对开源软件和AWS开发者体验!

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 TransferManager 为了Amazon S3操作

您可以使用 AWS SDK for Java TransferManager 类可靠地将文件从本地环境传输到 Amazon S3 并将对象从一个 S3 位置复制到另一个 S3 位置。TransferManager 可获取传输进度,以及暂停或恢复上传和下载。

注意

最佳实践

建议您对 存储桶启用 AbortIncompleteMultipartUploadAmazon S3 生命周期规则。

该规则指示 Amazon S3 中止在启动后没有在指定天数内完成的分段上传。当超过设置的时间限制时,Amazon S3 将中止上传,然后删除未完成的上传数据。

有关更多信息,请参阅 。带版本控制的存储桶的生命周期配置中的Amazon S3用户指南。

注意

这些代码示例假设你了解中的材料使用AWS SDK for Java并且已配置默认值AWS使用中的信息的凭据设置AWS发展凭证和区域.

上传文件和目录

TransferManager 可将文件、文件列表和目录上传到任何一个Amazon S3你拥有的存储桶以前创建的.

上传单个文件

致电 TransferManagerupload方法,提供Amazon S3存储桶名称、键(对象)名称和标准 JavaFile (文件)表示要上传的文件的对象。

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.MultipleFileUpload; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import java.io.File; import java.util.ArrayList; import java.util.Arrays;

代码

File f = new File(file_path); TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { Upload xfer = xfer_mgr.upload(bucket_name, key_name, f); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

upload 方法立即返回值,为您提供一个 Upload 对象,用于检查传输状态或等待传输完成。

请参阅请等待传输完成。有关将使用的信息waitForCompletion在致电 TransferManager 之前成功完成转移shutdownNow方法。在等待传输完成时,您可以轮询或侦听有关其状态和进度的更新。有关更多信息,请参阅获取传输状态和进度

请参阅 GitHub 上的完整示例

上传文件列表

要通过一次操作上传多个文件,请致电 TransferManageruploadFileList方法,并为其提供:

  • Amazon S3 存储桶名称

  • 一个键前缀,它将添加到创建的对象名称的前面 (将对象放置到的存储桶中的路径)

  • 一个 File 对象,此对象表示将从中创建文件路径的相对目录

  • 一个 List 对象,包含一组要上传的 File 对象

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.MultipleFileUpload; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import java.io.File; import java.util.ArrayList; import java.util.Arrays;

代码

ArrayList<File> files = new ArrayList<File>(); for (String path : file_paths) { files.add(new File(path)); } TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { MultipleFileUpload xfer = xfer_mgr.uploadFileList(bucket_name, key_prefix, new File("."), files); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅请等待传输完成。有关将使用的信息waitForCompletion在致电 TransferManager 之前成功完成转移shutdownNow方法。在等待传输完成时,您可以轮询或侦听有关其状态和进度的更新。有关更多信息,请参阅获取传输状态和进度

这些区域有:MultipleFileUpload返回的对象uploadFileList可用于查询传输状态或进度。有关更多信息,请参阅轮询传输的当前进度使用 ProgressListener 获取传输进度

您也可以使用 MultipleFileUploadgetSubTransfers 方法为要传输的每个文件获取单个 Upload 对象。有关更多信息,请参阅获取子传输的进度

请参阅 GitHub 上的完整示例

上传目录

您可以使用 TransferManager 的uploadDirectory用于上传整个文件目录的方法,并可以选择以递归方式复制子目录中的文件的选项。您提供一个 Amazon S3 存储桶名称、一个 S3 键前缀、一个表示要复制的本地目录的 File 对象和一个 boolean 值,该值指示您是否需要以递归方式复制子目录(truefalse)。

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.MultipleFileUpload; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import java.io.File; import java.util.ArrayList; import java.util.Arrays;

代码

TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { MultipleFileUpload xfer = xfer_mgr.uploadDirectory(bucket_name, key_prefix, new File(dir_path), recursive); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅请等待传输完成。有关将使用的信息waitForCompletion在致电 TransferManager 之前成功完成转移shutdownNow方法。在等待传输完成时,您可以轮询或侦听有关其状态和进度的更新。有关更多信息,请参阅获取传输状态和进度

这些区域有:MultipleFileUpload返回的对象uploadFileList可用于查询传输状态或进度。有关更多信息,请参阅轮询传输的当前进度使用 ProgressListener 获取传输进度

您也可以使用 MultipleFileUploadgetSubTransfers 方法为要传输的每个文件获取单个 Upload 对象。有关更多信息,请参阅获取子传输的进度

请参阅 GitHub 上的完整示例

下载文件或目录

使用 TransferManager 类来下载单个文件(Amazon S3对象)或目录(Amazon S3存储桶名称后跟数据元前缀)Amazon S3.

下载单个文件

使用 TransferManagerdownload方法,提供Amazon S3包含要下载的对象的存储桶名称、键(对象)名称和File (文件)表示要在本地系统上创建的文件的对象。

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.Download; import com.amazonaws.services.s3.transfer.MultipleFileDownload; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import java.io.File;

代码

File f = new File(file_path); TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { Download xfer = xfer_mgr.download(bucket_name, key_name, f); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅请等待传输完成。有关将使用的信息waitForCompletion在致电 TransferManager 之前成功完成转移shutdownNow方法。在等待传输完成时,您可以轮询或侦听有关其状态和进度的更新。有关更多信息,请参阅获取传输状态和进度

请参阅 GitHub 上的完整示例

下载目录

要从下载一组共享一个公共 key prefix 的文件(类似于文件系统上的目录)Amazon S3,使用 TransferManagerdownloadDirectory方法。该方法需要包含要下载的对象的 Amazon S3 存储桶名称、所有对象共享的对象前缀和一个 File 对象(此对象表示要将文件下载到的本地系统目录)。如果指定目录尚不存在,将创建此目录。

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.Download; import com.amazonaws.services.s3.transfer.MultipleFileDownload; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import java.io.File;

代码

TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { MultipleFileDownload xfer = xfer_mgr.downloadDirectory( bucket_name, key_prefix, new File(dir_path)); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅请等待传输完成。有关将使用的信息waitForCompletion在致电 TransferManager 之前成功完成转移shutdownNow方法。在等待传输完成时,您可以轮询或侦听有关其状态和进度的更新。有关更多信息,请参阅获取传输状态和进度

请参阅 GitHub 上的完整示例

复制对象

要将对象从一个 S3 存储桶复制到另一个 S3 存储桶,可使用 TransferManagercopy方法。

导入

import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.transfer.Copy; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder;

代码

System.out.println("Copying s3 object: " + from_key); System.out.println(" from bucket: " + from_bucket); System.out.println(" to s3 object: " + to_key); System.out.println(" in bucket: " + to_bucket); TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { Copy xfer = xfer_mgr.copy(from_bucket, from_key, to_bucket, to_key); // loop with Transfer.isDone() XferMgrProgress.showTransferProgress(xfer); // or block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(xfer); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅 GitHub 上的完整示例

请等待传输完成。

如果可以在传输完成前阻止您的应用程序(或线程),则可使用 Transfer 接口的 waitForCompletion 方法来阻止它,直至传输完成或出现异常。

try { xfer.waitForCompletion(); } catch (AmazonServiceException e) { System.err.println("Amazon service error: " + e.getMessage()); System.exit(1); } catch (AmazonClientException e) { System.err.println("Amazon client error: " + e.getMessage()); System.exit(1); } catch (InterruptedException e) { System.err.println("Transfer interrupted: " + e.getMessage()); System.exit(1); }

如果您在调用 之前waitForCompletion 轮询事件、在单独线程上实施轮询机制或使用 ProgressListener 异步接收进度更新,则可获取传输进度。

请参阅 GitHub 上的完整示例

获取传输状态和进度

TransferManager 返回的每个类upload*download*, 和copy方法所返回以下某个类的实例,具体取决于它是单文件操作还是多文件操作。

返回方

​复制

copy

下载

download

MultipleFileDownload

downloadDirectory

上传

upload

MultipleFileUpload

uploadFileList, uploadDirectory

所有这些类都实施 Transfer 接口。Transfer 提供了用于获取传输进度、暂停或恢复传输以及获取传输的当前状态或最终状态的有用方法。

轮询传输的当前进度

此循环打印传输的进度,在其运行时检查其当前进度,然后在传输完成时打印最终状态。

导入

import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.event.ProgressEvent; import com.amazonaws.event.ProgressListener; import com.amazonaws.services.s3.transfer.*; import com.amazonaws.services.s3.transfer.Transfer.TransferState; import java.io.File; import java.util.ArrayList; import java.util.Collection;

代码

// print the transfer's human-readable description System.out.println(xfer.getDescription()); // print an empty progress bar... printProgressBar(0.0); // update the progress bar while the xfer is ongoing. do { try { Thread.sleep(100); } catch (InterruptedException e) { return; } // Note: so_far and total aren't used, they're just for // documentation purposes. TransferProgress progress = xfer.getProgress(); long so_far = progress.getBytesTransferred(); long total = progress.getTotalBytesToTransfer(); double pct = progress.getPercentTransferred(); eraseProgressBar(); printProgressBar(pct); } while (xfer.isDone() == false); // print the final state of the transfer. TransferState xfer_state = xfer.getState(); System.out.println(": " + xfer_state);

请参阅 GitHub 上的完整示例

使用 ProgressListener 获取传输进度

您可以附加ProgressListener通过使用转移接口的addProgressListener方法。

ProgressListener 只需要一个方法,即 progressChanged,此方法将采用 ProgressEvent 对象。您可以使用此对象获取操作的总字节数 (通过调用其 getBytes 方法) 和目前已传输的字节数 (通过调用 getBytesTransferred)。

导入

import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.event.ProgressEvent; import com.amazonaws.event.ProgressListener; import com.amazonaws.services.s3.transfer.*; import com.amazonaws.services.s3.transfer.Transfer.TransferState; import java.io.File; import java.util.ArrayList; import java.util.Collection;

代码

File f = new File(file_path); TransferManager xfer_mgr = TransferManagerBuilder.standard().build(); try { Upload u = xfer_mgr.upload(bucket_name, key_name, f); // print an empty progress bar... printProgressBar(0.0); u.addProgressListener(new ProgressListener() { public void progressChanged(ProgressEvent e) { double pct = e.getBytesTransferred() * 100.0 / e.getBytes(); eraseProgressBar(); printProgressBar(pct); } }); // block with Transfer.waitForCompletion() XferMgrProgress.waitForCompletion(u); // print the final state of the transfer. TransferState xfer_state = u.getState(); System.out.println(": " + xfer_state); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } xfer_mgr.shutdownNow();

请参阅 GitHub 上的完整示例

获取子传输的进度

MultipleFileUpload 类可通过调用其 getSubTransfers 方法来返回有关其子传输的信息。它返回不可修改的集合上传提供每个子传输的单独传输状态和进度的对象。

导入

import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.event.ProgressEvent; import com.amazonaws.event.ProgressListener; import com.amazonaws.services.s3.transfer.*; import com.amazonaws.services.s3.transfer.Transfer.TransferState; import java.io.File; import java.util.ArrayList; import java.util.Collection;

代码

Collection<? extends Upload> sub_xfers = new ArrayList<Upload>(); sub_xfers = multi_upload.getSubTransfers(); do { System.out.println("\nSubtransfer progress:\n"); for (Upload u : sub_xfers) { System.out.println(" " + u.getDescription()); if (u.isDone()) { TransferState xfer_state = u.getState(); System.out.println(" " + xfer_state); } else { TransferProgress progress = u.getProgress(); double pct = progress.getPercentTransferred(); printProgressBar(pct); System.out.println(); } } // wait a bit before the next update. try { Thread.sleep(200); } catch (InterruptedException e) { return; } } while (multi_upload.isDone() == false); // print the final state of the transfer. TransferState xfer_state = multi_upload.getState(); System.out.println("\nMultipleFileUpload " + xfer_state);

请参阅 GitHub 上的完整示例

更多信息

  • 对象键中的Amazon Simple Storage Service用户指南