AWS S3文件存储工具类
/** * 提供对aws s3 文件操作 * * @auther xushy * since 20200724 */ //@Slf4j @Component public class S3Util { private BasicAWSCredentials awsCreds = null; private AmazonS3 s3 = null; @Autowired S3Config s3Config; @PostConstruct public void init() { /** * 创建s3对象 */ if (StringUtils.isNotBlank(s3Config.getAccessKey()) && StringUtils.isNotBlank(s3Config.getSecretKey())) { awsCreds = new BasicAWSCredentials(s3Config.getAccessKey(), s3Config.getSecretKey()); s3 = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) .withRegion(Regions.fromName(s3Config.getRegion())) .build(); } } /** * 上传文件 * * @param file 文件 */ public String uploadFile(MultipartFile file, String moduleName) { return uploadFile(file, ConflictPolicy.NEW, moduleName); } /** * @param file * @param policy 冲突策略,当同一路径下有同名文件时可选。默认是替换同名文件 * @param moduleName 项目内的模块名 * @return */ public String uploadFile(MultipartFile file, ConflictPolicy policy, String moduleName) { if (isEmpty(file)) { return null; } // 生成临时文件 File localFile = null; try { //先从s3服务器上查找是否有同名文件 String key = s3Config.getProject() + "/" + moduleName + "/" + file.getOriginalFilename(); localFile = File.createTempFile("temp", null); file.transferTo(localFile); String prefix = key.substring(0, key.lastIndexOf(".")); String suffix = key.substring(key.indexOf(".")); //取出同名文件的最大number int maxNum = getMaxVersionNum(s3Config.getBucketName(), prefix, suffix); if (maxNum != -1) { switch (policy) { case NEW: key = prefix + "(" + (++maxNum) + ")" + suffix; break; case RETAIN: return "文件已存在,根据冲突策略,文件不予替换"; case REPLACE: default: break; } } PutObjectRequest request = new PutObjectRequest(s3Config.getBucketName(), key, localFile); // 上传文件 如果没抛异常则可认为上传成功 PutObjectResult putObjectResult = s3.putObject(request); if (StringUtils.isNotEmpty(putObjectResult.getETag())) { return key; } return null; } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (localFile != null) { localFile.delete(); } } return null; } private int getMaxVersionNum(String bucketName, String prefix, String suffix) { ListObjectsRequest listRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix(prefix).withMaxKeys(100); ObjectListing objectListing = s3.listObjects(listRequest); int value = -1; for (S3ObjectSummary inst : objectListing.getObjectSummaries()) { String indexStr = inst.getKey().replace(prefix, "").replace("(", "").replace(")", "").replace(suffix, ""); if (indexStr.length() == 0) { indexStr = "0"; } value = Math.max(value, Integer.parseInt(indexStr)); } return value; } /** * 删除单个文件 * * @param key 根据key删除文件 * @return */ public void deleteObject(String key) { if (StringUtils.isBlank(key)) { throw new IllegalArgumentException("key can not be null"); } s3.deleteObject(s3Config.getBucketName(), key); } /** * @param key 根据key得到文件的输入流 * @return */ public S3ObjectInputStream getFileInputStream(String key) { S3Object object = s3.getObject(new GetObjectRequest(s3Config.getBucketName(), key)); return object.getObjectContent(); } /** * 根据key得到输入流并输出到输出流 * * @param key * @param stream */ public void downloadFile(String key, OutputStream stream) { InputStream input = getFileInputStream(key); byte[] data = null; try { data = new byte[input.available()]; int len = 0; while ((len = input.read(data)) != -1) { stream.write(data, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 根据key得到输入流并输出到输出流 * * @param key * @param response */ public void downloadFile(String key, HttpServletResponse response) { String fileName = key; byte[] data = null; OutputStream stream = null; InputStream input = getFileInputStream(key); if (key.contains("/")) { String[] path = key.split("/"); fileName = path[path.length - 1]; } response.setHeader("Content-Disposition", "attachment; filename=" + fileName); try { stream = response.getOutputStream(); data = new byte[input.available()]; int len = 0; while ((len = input.read(data)) != -1) { stream.write(data, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 删除文件夹 * * @param filePath 文件夹地址[ eg:temp/1 或 temp ] * @param deleteAll true-递进删除所有文件(包括子文件夹);false-只删除当前文件夹下的文件,不删除子文件夹内容 */ public void deleteFolder(String filePath, boolean deleteAll) { ListObjectsV2Request objectsRequest = new ListObjectsV2Request(); objectsRequest.setBucketName(s3Config.getBucketName()); objectsRequest.setPrefix(filePath); // deliter表示分隔符, 设置为/表示列出当前目录下的object, 设置为空表示列出所有的object objectsRequest.setDelimiter(deleteAll ? "" : "/"); // 设置最大遍历出多少个对象, 一次listobject最大支持1000 objectsRequest.setMaxKeys(1000); ListObjectsV2Result listObjectsRequest = s3.listObjectsV2(objectsRequest); List<S3ObjectSummary> objects = listObjectsRequest.getObjectSummaries(); String[] object_keys = new String[objects.size()]; for (int i = 0; i < objects.size(); i++) { S3ObjectSummary item = objects.get(i); object_keys[i] = item.getKey(); } DeleteObjectsRequest dor = new DeleteObjectsRequest(s3Config.getBucketName()).withKeys(object_keys); s3.deleteObjects(dor); } /** * 检查文件是否为空 * * @param * @return */ public boolean isEmpty(MultipartFile file) { if (file == null || file.getSize() <= 0) { return true; } return false; } /** * 得到所有文件的key * * @return key list */ public List<String> getFileKeys() { List<String> keys = new LinkedList<>(); ListObjectsRequest listRequest = new ListObjectsRequest().withBucketName(s3Config.getBucketName()); try { ObjectListing objects = s3.listObjects(listRequest); while (true) { List<S3ObjectSummary> summaries = objects.getObjectSummaries(); for (S3ObjectSummary summary : summaries) { keys.add(summary.getKey()); } if (objects.isTruncated()) { objects = s3.listNextBatchOfObjects(objects); } else { break; } } } catch (Exception exception) { exception.printStackTrace(); } return keys; } }
public enum ConflictPolicy {
REPLACE, NEW, RETAIN
}
@Component
@ConfigurationProperties(prefix="aws.s3")
public class S3Config {
private String accessKey;
private String secretKey;
private String bucketName;
private String region;
private String project;
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
}
application.yml
aws:
s3:
accessKey:
secretKey:
bucketName:
region: cn-north-1
project: