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:
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM