网站加载速率,前端网站开发研究报告,wordpress 多说插件,做刷网站怎么赚钱从零开始#xff1a;Java与AWS S3的文件操作 一、什么是 AWS S3#xff1f;AWS S3 的特点AWS S3 的应用场景 二、Java整合S3方法使用 MinIO 客户端操作 S3使用 AWS SDK 操作 S3 #xff08;推荐使用#xff09; 三、总结 一、什么是 AWS S3#xff1f;
Amazon Simple Sto… 从零开始Java与AWS S3的文件操作 一、什么是 AWS S3AWS S3 的特点AWS S3 的应用场景 二、Java整合S3方法使用 MinIO 客户端操作 S3使用 AWS SDK 操作 S3 推荐使用 三、总结 一、什么是 AWS S3
Amazon Simple Storage Service简称 Amazon S3是由亚马逊网络服务AWS提供的一种对象存储服务。它提供了一个高度可扩展、持久、安全且低成本的存储解决方案用于存储和检索任意数量的数据。
AWS S3 的特点
高可用性和持久性 AWS S3 的设计目标是为存储的数据提供 99.999999999%11个9的持久性并确保 99.99% 的可用性。 数据会自动在多个地理位置冗余存储以保证数据的高持久性和可用性。
安全性
AWS S3 提供了多种安全措施包括传输中和存储时的数据加密、细粒度的访问控制策略、以及与 AWS Identity and Access Management (IAM) 集成的用户认证机制。
可扩展性 AWS S3 可以自动扩展以处理从几字节到数十亿字节的数据。 用户无需预先配置存储容量且可以根据需要动态增加或减少存储容量。
成本效益 AWS S3 提供按需付费的计费模式根据实际使用量收费没有预付费用或最低消费。 用户可以选择不同的存储类别如标准存储、智能分层存储、归档存储等以优化存储成本。
简单易用 AWS S3 提供了简单的 REST 和 SOAP API开发人员可以方便地进行集成和操作。 AWS S3 管理控制台提供了直观的用户界面用于管理存储桶和对象。
灵活的数据管理
支持版本控制、生命周期管理、事件通知和跨区域复制等高级功能帮助用户更好地管理数据。
高效的上传和下载速度 AWS S3 提供了高效的数据传输速度支持大规模数据的快速上传和下载。 上传速度在良好的网络条件下单个文件的上传速度可以达到数百兆比特每秒 (Mbps)。 下载速度下载速度也可以达到数百兆比特每秒 (Mbps)尤其是在使用 Amazon CloudFront 进行内容分发时。 S3 Transfer Acceleration通过启用 S3 Transfer Acceleration可以进一步提升上传速度全球范围内的传输速度可以提高 50-500% 以上具体提升取决于用户的地理位置和网络条件。
AWS S3 的应用场景
静态网站托管
AWS S3 可以用于托管静态网站包括 HTML、CSS、JavaScript 文件等。
备份和恢复
作为企业级备份解决方案AWS S3 可以用于存储备份数据支持高持久性和快速恢复。
大数据分析 数据湖AWS S3 可以作为数据湖用于存储和分析大规模的结构化和非结构化数据。 与 AWS 分析服务如 Amazon Redshift、Amazon Athena集成进行大数据分析。
媒体存储和分发
AWS S3 可以存储大量的媒体文件如图片、视频、音频并通过 Content Delivery Network (CDN) 进行全球分发。
日志存储
服务器和应用程序的日志可以存储在 AWS S3 中以便于后续的分析和监控。
软件分发
企业可以使用 AWS S3 进行软件包和应用程序更新的分发。
容灾和跨区域复制
利用跨区域复制功能企业可以在多个地理位置间复制数据提高容灾能力。
二、Java整合S3方法
在 Java 中可以通过两种主要方法与 S3 服务器进行交互使用 MinIO 客户端和使用 AWS SDK。两者都能与 S3 服务兼容但它们在使用方式和配置上有所不同。
使用 MinIO 客户端操作 S3
MinIO 是一个兼容 S3 API 的开源对象存储解决方案。它提供了与 AWS S3 相同的接口因此可以使用 MinIO 的 SDK 来操作 S3 存储服务。MinIO 客户端非常适合在本地部署的 S3 兼容存储如 MinIO 自身和 AWS S3 上进行文件操作。
优点 轻量级、开源适合本地部署或私有云环境。 与 AWS S3 完全兼容支持所有 S3 操作如上传、下载、删除文件等。
添加依赖 !-- S3存储服务依赖 minio --dependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.5.5/version/dependency配置AWS S3相关的信息
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;/*** CreateTime: 2024/05/31 18:17* Description: S3配置文件* Version: 1.0*/
Component
public class S3Config {Value(${spring.s3_config.bucket_name})private String bucketName;Value(${spring.s3_config.endpoint})private String s3Endpoint;Value(${spring.s3_config.aws_access_key_id})private String awsAccessKeyId;Value(${spring.s3_config.aws_secret_access_key})private String awsSecretAccessKey;private MinioClient minioClient;PostConstructpublic void init() {// 初始化 MinioClientminioClient MinioClient.builder().endpoint(s3Endpoint)// s3服务器端点地址.credentials(awsAccessKeyId, awsSecretAccessKey)// 设置 访问凭证.build();}/*** 获取桶名*/public String getBucketName() {return bucketName;}/*** 获取minio客户端*/public MinioClient getMinioClient() {return minioClient;}
}
生成 S3 预览链接 /*** description: 生成 S3 预览链接* param realPath 生成 S3 预览链接的真实地址* return 如果成功生成预览链接则返回链接字符串否则返回 null*/public static String generatePreviewUrl(String realPath) {try {// 创建额外的请求参数这里设置响应内容类型MapString, String reqParams new HashMap();String contentType FileEnum.getByExtension(realPath.substring(realPath.lastIndexOf(.) 1)).getContentType();reqParams.put(response-content-type, contentType);// 使用 MinIO 客户端生成预签名的对象 URLreturn minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET) // 指定请求方法为 GET.bucket(bucketName) // 指定存储桶名称.object(realPath) // 指定对象名称.extraQueryParams(reqParams) // 添加额外的查询参数这里是响应内容类型.expiry(7, TimeUnit.DAYS) // 指定预签名 URL 的有效期.build());} catch (Exception e) {// 捕获并打印任何异常log.error(生成预览链接失败: e);throw new RuntimeException(生成预览链接失败);}}上传文件到S3 /*** description: 上传文件到S3* param file 上传的文件* return 如果成功上传返回 true否则返回 false*/public static String uploadFile(MultipartFile file) {try {// 获取上传的文件String fileName file.getOriginalFilename();// 参数验证确保文件名不为空if (fileName null || fileName.isEmpty()) {throw new ServiceException(文件名无效);}String path projectPath fileName;// 使用 MinIO 客户端将文件上传到 S3 存储桶try (InputStream fileStream file.getInputStream()) {minioClient.putObject(PutObjectArgs.builder().bucket(bucketName) // 指定存储桶名称.object(path) // 指定对象名称.stream(fileStream, file.getSize(), -1) // 输入流和大小.build());}return path;} catch (Exception e) {// 捕获并打印 MinIO 异常信息log.error(上传文件失败: e);throw new RuntimeException(上传文件失败);}}删除 S3 文件 /*** description: 删除 S3 文件* param fileUrl 要删除的文件的 URL 或对象名称*/public static void removeFile(String realPath) {try {// 使用 MinIO 客户端删除对象minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName) // 指定存储桶名称.object(realPath) // 指定要删除的对象名称或 URL.build());} catch (Exception e) {log.error(文件删除失败: e);throw new RuntimeException(文件删除失败);}}从s3获取文件流
当在大批量并发获取大文件流时minio的方式可能会出现获取缓慢、卡死或中断的情况推荐采用第二种方法AWS SDK的方式去获取文件流 /*** description: 通过realPath获取文件流* param: realPath* return: InputStream **/public static InputStream downloadByS3Url(String realPath) throws IOException {try {// 获取文件流InputStream fis minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(realPath).build());return fis;} catch (Exception e) {log.error(获取文件流失败: e);throw new RuntimeException(获取文件流失败);}}从s3下载文件 /*** 下载文件* param filePath MinIO 中的文件路径* param downloadPath 本地下载路径*/public static void downloadFile(String filePath, String downloadPath) {try {// 使用 getObject 获取文件InputStream fileStream minioClient.getObject(GetObjectArgs.builder().bucket(bucketName) // 指定存储桶名称.object(filePath) // 指定文件路径.build());// 将文件内容写入到本地文件Path path Paths.get(downloadPath);Files.copy(fileStream, path);System.out.println(文件已成功下载到: downloadPath);} catch (MinioException e) {log.error(下载文件失败: e);throw new RuntimeException(MinIO 下载文件失败);} catch (IOException e) {log.error(保存文件到本地时失败: e);throw new RuntimeException(保存文件到本地时失败);}}使用 AWS SDK 操作 S3 推荐使用
AWS SDK 是 Amazon 提供的官方库用于与 AWS 服务包括 S3进行交互。它不仅支持 AWS S3还能支持其他 AWS 服务如 EC2、DynamoDB 等。如果你使用的是 AWS S3 或希望利用 AWS 的其它功能AWS SDK 是推荐的选择。
优点 官方支持功能全面适用于使用 AWS 云服务的场景。 可以访问 AWS 特有的功能和工具。
添加依赖 !-- S3存储服务依赖 AWS SDK --dependencygroupIdsoftware.amazon.awssdk/groupIdartifactIds3/artifactIdversion2.17.85/version/dependency配置AWS S3相关的信息
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;import javax.annotation.PostConstruct;
import java.net.URI;
import java.time.Duration;/*** CreateTime: 2024/05/31 18:17* Description: S3配置文件* Version: 1.0*/
Component
public class S3Config {Value(${spring.s3_config.bucket_name})private String bucketName;Value(${spring.s3_config.endpoint})private String s3Endpoint;Value(${spring.s3_config.aws_access_key_id})private String awsAccessKeyId;Value(${spring.s3_config.aws_secret_access_key})private String awsSecretAccessKey;private S3Client s3Client;PostConstructpublic void init() {// 将凭证作为类级别的静态变量避免每次调用都创建AwsBasicCredentials awsCredentials AwsBasicCredentials.create(awsAccessKeyId, awsSecretAccessKey);s3Client S3Client.builder().region(Region.US_EAST_1) // 选择正确的区域.endpointOverride(URI.create(s3Endpoint))// s3 服务器端点地址.credentialsProvider(StaticCredentialsProvider.create(awsCredentials)).overrideConfiguration(ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofMinutes(10)) // 设置整个请求的最大超时为 10 分钟.apiCallAttemptTimeout(Duration.ofMinutes(9)) // 每次尝试的最大超时为 9 分钟.build()).build();}/*** 获取桶名*/public String getBucketName() {return bucketName;}/*** 获取亚马逊s3客户端*/public S3Client getS3Client() {return s3Client;}
}生成 S3 预览链接 /*** description: 生成 S3 预览链接* param realPath 生成 S3 预览链接的真实地址* return 如果成功生成预览链接则返回链接字符串否则返回 null*/public static String generatePreviewUrl(String realPath) {try {// 创建 S3Presigner 实例private static final S3Presigner presigner S3Presigner.builder().region(Region.US_EAST_1) // 选择正确的区域.credentialsProvider(StaticCredentialsProvider.create(awsCredentials)).build();// 获取文件扩展名并根据扩展名获取内容类型String extension realPath.substring(realPath.lastIndexOf(.) 1);String contentType FileEnum.getByExtension(extension).getContentType();// 构建 GetObjectRequest 对象GetObjectRequest getObjectRequest GetObjectRequest.builder().bucket(bucketName).key(realPath).responseContentType(contentType) // 设置响应内容类型.build();// 构建 GetObjectPresignRequest 对象GetObjectPresignRequest getObjectPresignRequest GetObjectPresignRequest.builder().signatureDuration(Duration.ofDays(7)) // 设置预签名 URL 的有效期.getObjectRequest(getObjectRequest).build();// 生成预签名的 URLreturn presigner.presignGetObject(getObjectPresignRequest).url().toString();} catch (Exception e) {// 捕获并打印任何异常log.error(生成预览链接失败: e);throw new RuntimeException(生成预览链接失败);}}上传文件到S3 /*** description: 上传文件到S3* param file 上传的文件* return 如果成功上传返回 true否则返回 false*/public static String uploadFile(MultipartFile file) {try {// 获取上传的文件String fileName file.getOriginalFilename();// 参数验证确保文件名不为空if (fileName null || fileName.isEmpty()) {throw new ServiceException(文件名无效);}String path projectPath fileName; // 在S3存储桶中存储的路径// 获取文件输入流try (InputStream fileStream file.getInputStream()) {// 创建 PutObjectRequestPutObjectRequest putObjectRequest PutObjectRequest.builder().bucket(bucketName).key(path) // 设置 S3 存储对象的路径.build();// 上传文件到 S3PutObjectResponse putObjectResponse s3Client.putObject(putObjectRequest,RequestBody.fromInputStream(fileStream, file.getSize()));// 返回上传文件的路径return path;} catch (Exception e) {log.error(上传文件失败: e);throw new RuntimeException(上传文件失败);}}删除 S3 文件 /*** description: 删除 S3 文件* param fileUrl 要删除的文件的 URL 或对象名称*/public static void removeFile(String realPath) {try {// 创建删除文件的请求对象DeleteObjectRequest deleteObjectRequest DeleteObjectRequest.builder().bucket(bucketName) // 存储桶名称.key(realPath) // 文件路径.build();// 执行文件删除操作s3Client.deleteObject(deleteObjectRequest);} catch (Exception e) {log.error(文件删除失败: e);throw new RuntimeException(文件删除失败);}}从s3获取文件流
/*** description: 通过realPath获取文件流* param: realPath* return: InputStream **/public static InputStream downloadByS3Url(String realPath) throws IOException {try {// 创建 GetObjectRequest 请求指定存储桶名称和对象键GetObjectRequest getObjectRequest GetObjectRequest.builder().bucket(bucketName) // S3 存储桶名称.key(realPath) // S3 对象键.build();// 获取对象并返回文件的输入流InputStream fis s3Client.getObject(getObjectRequest); // 获取文件输入流return fis;} catch (Exception e) {log.error(获取文件流失败: e);throw new RuntimeException(获取文件流失败);}}从s3下载文件
/*** description: 从 S3 下载文件* param filePath 要下载的文件路径* param downloadPath 本地存储路径*/public static void downloadFile(String filePath, String downloadPath) {try {// 创建 GetObjectRequest 请求GetObjectRequest getObjectRequest GetObjectRequest.builder().bucket(bucketName) // 存储桶名称.key(filePath) // S3 中的文件路径.build();// 执行下载操作并获取文件响应GetObjectResponse getObjectResponse s3Client.getObject(getObjectRequest,Paths.get(downloadPath)); // 下载到指定路径// 处理下载后的响应如果需要可以做进一步处理System.out.println(文件已下载: getObjectResponse);} catch (S3Exception e) {// 捕获 AWS S3 异常并记录错误log.error(文件下载失败: e.awsErrorDetails().errorMessage());throw new RuntimeException(文件下载失败);} catch (Exception e) {// 捕获其他异常log.error(文件下载失败: e);throw new RuntimeException(文件下载失败);}}三、总结
MinIO 客户端
适用于本地部署的 S3 兼容存储或者想要避免依赖 AWS 提供的 SDK。通过 MinIO你可以在 S3 和 MinIO 之间无缝迁移或用于私有云环境。
AWS SDK
适用于直接操作 AWS S3 服务提供更多 AWS 的特性和功能支持。如果你的应用已经在 AWS 云上运行使用 AWS SDK 是更理想的选择。