一、Amazon S3介绍:
官方介绍:amazon (S3) 是一个公开的服务,Web 应用程序开发人员可以使用它存储数字资产,包括图片、视频、音乐和文档。 S3 提供一个 RESTful API 以编程方式实现与该服务的交互。
通俗理解:以桶作为容器。以桶内全路径作为key,以文件作为value的文件存储方式
二、springboot集成Amazon s3
在项目的pom文件中增加如下依赖
com.amazonaws aws-java-sdk-s31.11.336 com.amazonaws aws-java-sdk-core1.11.336 com.amazonaws aws-java-sdk-kms1.11.336
三、Amazon S3工具类
实现功能:
方法 | 方法名 |
创建s3的客户端连接 | public AmazonS3 createS3Client(String accessKeyId,String secretAccessKey,String endPoint) |
上传文件 | public boolean uploadFile(File file, String fileKey) |
上传文件流 | public boolean uploadFileByStream(InputStream inputStream, String fileKey) |
从s3下载文件 | public InputStream downloadFile(String fileKey)
|
同一个桶内移动文件 | public boolean mvFile(String oldFileKey,String newFileKey)
|
删除单个文件 | public boolean deleteFile(String fileKey)
|
删除多个文件 | public boolean deleteFiles(String[] fileList)
|
查看文件是否存在 | public boolean exist(String fileKey)
|
根据prefix获取文件列表 | public List
|
生成文件的预签名url | public String generalUrl(String fileKey)
|
根据预签名url下载文件 | public File downloadFromUrl(String url,String filePath)
|
package com.testcase.s3; import com.amazonaws.ClientConfiguration; import com.amazonaws.HttpMethod; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; /** * Created with IntelliJ IDEA. * Description:Amazon s3工具类 * User: rice */ @Log4j2 public class S3ToolUtils { //S3访问密钥 private String accessKeyId; //S3加密访问密钥 private String secretAccessKey; //服务端点 private String endPoint; //桶名 private String bucketName; public S3ToolUtils(String accessKeyId, String secretAccessKey, String endPoint) { this.accessKeyId = accessKeyId; this.secretAccessKey = secretAccessKey; this.endPoint = endPoint; this.bucketName = bucketName; } /** * 创建一个对象存储桶客户端连接 * @param accessKeyId:AWS访问密钥 * @param secretAccessKey:AWS加密访问密钥 * @param endPoint:服务端点 * @return AmazonS3 */ public AmazonS3 createS3Client(String accessKeyId,String secretAccessKey,String endPoint){ //创建s3 client ClientConfiguration clientConfiguration = new ClientConfiguration(); //添加客户端最大连接数 clientConfiguration.setMaxConnections(1000); AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey); AmazonS3 client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, Regions.CN_NORTH_1.getName())) .withClientConfiguration(clientConfiguration) .withPathStyleAccessEnabled(true).build(); return client; } /** * 上传文件到对象存储桶 * @param file * @param fileKey * @return Boolean */ public boolean uploadFile(File file, String fileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //上传文件 s3Client.putObject(bucketName,fileKey,file); }catch (Exception e){ log.error(e); return false; } return true; } /** * 上传文件到对象存储桶-文件流方式 * @param inputStream * @param fileKey * @return boolean */ public boolean uploadFileByStream(InputStream inputStream, String fileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //上传文件 s3Client.putObject(bucketName,fileKey,inputStream,new ObjectMetadata()); }catch (Exception e){ log.error(e); return false; } return true; } /** * 下载文件 * @param fileKey * @return */ public InputStream downloadFile(String fileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //上传文件 S3Object object = s3Client.getObject(bucketName, fileKey); return object.getObjectContent(); }catch (Exception e){ log.error(e); return null; } } /** * 移动文件(删除原文件) * @param oldFileKey 原全路径 * @param newFileKey 新全路径 * @return boolean */ public boolean mvFile(String oldFileKey,String newFileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //复制文件 CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, oldFileKey, bucketName, newFileKey); s3Client.copyObject(copyObjectRequest); //删除原文件 s3Client.deleteObject(new DeleteObjectRequest(bucketName,oldFileKey)); }catch (Exception e){ log.error(e); return false; } return true; } /** * 删除文件 * @param fileKey 删除文件全路径 * @return boolean */ public boolean deleteFile(String fileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //删除文件 s3Client.deleteObject(bucketName,fileKey); }catch (Exception e){ log.error(e); return false; } return true; } /** * 删除文件列表 * @param fileList * @return */ public boolean deleteFiles(String[] fileList){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //删除多个文件 DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(fileList); s3Client.deleteObjects(deleteObjectsRequest); }catch (Exception e){ log.error(e); return false; } return true; } /** * 查找桶内文件是否存在 * @param fileKey * @return */ public boolean exist(String fileKey){ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); ListObjectsV2Result listObjectsV2Result = s3Client.listObjectsV2(bucketName, fileKey); return listObjectsV2Result.getKeyCount()>0; } /** * 根据prefix获取文件列表 * 注意:若不进行do-while,只进行一次s3Client.listObjectsV2(req),则最多展示1000条 * @param prefix * @return */ public ListsearchPathFileByPrefix(String prefix){ ArrayList returnList = new ArrayList<>(); try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //按prefix获取文件列表 ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucketName); ListObjectsV2Result result; if(prefix!=null &&!prefix.isEmpty()){ req = req.withPrefix(prefix); } do{ result = s3Client.listObjectsV2(req); returnList.addAll(result.getObjectSummaries()); String token = result.getNextContinuationToken(); req.setContinuationToken(token); }while(result.isTruncated()); return returnList; }catch (Exception e){ log.error(e); return null; } } /** * 生成文件的预签名URL * 注意: * 1.有url,无需通过密钥连接对象存储桶,只用http请求就能下载文件 * 2.url最多7天有效,官方限制。所以必须考虑url刷新 * @param fileKey * @return */ public String generalUrl(String fileKey){ try{ //获取客户端连接 AmazonS3 s3Client = this.createS3Client(accessKeyId,secretAccessKey,endPoint); //设置预签名失效时间-最多七天 Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.DAY_OF_MONTH,7); Date date = calendar.getTime(); //生成预签名链接 GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileKey) .withMethod(HttpMethod.GET) .withExpiration(date); URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest); return url.toString(); }catch (Exception e){ log.error(e); return null; } } /** * 根据url下载文件到本地 * @param url * @param filePath * @return * @throws IOException */ public File downloadFromUrl(String url,String filePath) throws IOException { //获取文件名 String tmpUrl = StringUtils.substring(url,url.indexOf("//")+2); int startPos = StringUtils.indexOf(tmpUrl,"/",tmpUrl.indexOf("/")+1)+1; int endPos = StringUtils.indexOf(tmpUrl,"?"); tmpUrl = StringUtils.substring(tmpUrl,startPos,endPos); String fileName = Paths.get(StringUtils.replace(tmpUrl,"%2F","/")).getFileName().toString(); //http请求 HttpClient client = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); //输出文件 File file = new File(filePath + "/" + fileName); if(!file.getParentFile().exists()&&!file.getParentFile().isDirectory()){ file.getParentFile().mkdir(); } try(InputStream is = entity.getContent(); FileOutputStream fileout = new FileOutputStream(file)){ byte[] buffer = new byte[10 * 1024]; int ch = 0; while((ch = is.read(buffer))!=-1){ fileout.write(buffer,0,ch); } fileout.flush(); return file; }catch (Exception e){ return null; } } }
四、总结:
Amazon s3可以替代nas进行文件存储,在分布式架构中非常适用。
除了以上基础的使用外,还有分片下载、断点续传、异常处理等场景以及s3Browser工具的使用,后续进行分享。
PS:若有错漏,欢迎大家指正与讨论,谢谢~
还没有评论,来说两句吧...