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:
 

 

posted on 2020-08-31 16:13  xushy  阅读(1445)  评论(1编辑  收藏  举报

导航