minio文件加密/文件切割合并
生活随笔
收集整理的這篇文章主要介紹了
minio文件加密/文件切割合并
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
springboot2.x + minio7.0.2
本文記錄?minio的調用關鍵步驟和關鍵文檔. ?主要記錄大文件分片上傳和文件合并記錄
-?minio官網地址 ?http://www.minio.org.cn
-?minio 安裝參考官網說明
-?mino 文件加密需要https證書. 可以使用簽名證書
-?minio?服務啟動腳本 start.sh
#!/bin/bashexport MINIO_ACCESS_KEY=admin export MINIO_SECRET_KEY=admin123# minio 存放位置 dir=/data/menhu/minio# https證書位置minio/certs $dir/minio --certs-dir $dir/certs/ server $dir/data/minio &> $dir/logs/minio.log &minio 客戶端maven配置
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.0.2</version> </dependency>minio?配置類
/*** minio 配置類** @author dennis* @date 2021/5/26*/ @Component public class MinioConfig {@Value("${minio.host:https://play.min.io}")private String host;@Value("${minio.accessKey:Q3AM3UQ867SPQQA43P2F}")private String accessKey;@Value("${minio.secretKey:zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG}")private String secretKey;// 文件是否加密存儲@Value("${minio.encryption:false}")private Boolean encryption;@Beanpublic MinioClient getMinioClient() {try {MinioClient minioClient = new MinioClient(host, accessKey, secretKey);minioClient.ignoreCertCheck(); //忽略自簽名證書有效性return minioClient;} catch (Exception e) {e.printStackTrace();throw new ValidatorException(e.fillInStackTrace().getMessage());}}/*** 如何是https環境可以啟用 文件加密* @return*/public SecretKey getSecretKey() {if (encryption && StringUtils.startsWith(host, "https")) {try {KeyGenerator aes = KeyGenerator.getInstance("AES");aes.init(256);return aes.generateKey();} catch (Exception e) {e.printStackTrace();}}return null;} }minio 工具類
/*** minio 工具類** @author dennis* @date 2021/5/26*/ @Component public class MinioUtil {@Autowiredprivate MinioClient minioClient;private static final int DEFAULT_EXPIRY_TIME = 7 * 24 * 3600;/*** 檢查存儲桶是否存在** @param bucketName 存儲桶名稱* @return* @throws Exception*/public boolean bucketExists(String bucketName) throws Exception {return minioClient.bucketExists(bucketName);}/*** 創建存儲桶** @param bucketName 存儲桶名稱* @return* @throws Exception*/public boolean makeBucket(String bucketName) throws Exception {boolean flag = bucketExists(bucketName);if (!flag) {minioClient.makeBucket(bucketName);return true;}return false;}/*** 文件上傳** @param bucketName* @param multipartFile*/public void putObject(String bucketName, MultipartFile multipartFile, String filename, SecretKey secretKey) throws Exception {makeBucket(bucketName);PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);putObjectOptions.setContentType(multipartFile.getContentType());if (null != secretKey) {putObjectOptions.setSse(ServerSideEncryption.withCustomerKey(secretKey));}minioClient.putObject(bucketName, filename, multipartFile.getInputStream(), putObjectOptions);}/*** 以流的形式獲取一個文件對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @return*/public InputStream getObject(String bucketName, String objectName, SecretKey secretKey) throws Exception {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = statObject(bucketName, objectName, secretKey);if (statObject != null && statObject.length() > 0) {if (null != secretKey) {return minioClient.getObject(bucketName, objectName, ServerSideEncryption.withCustomerKey(secretKey));}return minioClient.getObject(bucketName, objectName);}}return null;}/*** 以流的形式獲取一個文件對象(斷點下載)** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param offset 起始字節的位置* @param length 要讀取的長度 (可選,如果無值則代表讀到文件結尾)* @return*/public InputStream getObject(String bucketName, String objectName, long offset, Long length, SecretKey secretKey) throws Exception {boolean flag = bucketExists(bucketName);if (flag) {ObjectStat statObject = statObject(bucketName, objectName, secretKey);if (statObject != null && statObject.length() > 0) {if (null != secretKey) {return minioClient.getObject(bucketName, objectName, offset, length, ServerSideEncryption.withCustomerKey(secretKey));}return minioClient.getObject(bucketName, objectName, offset, length);}}return null;}/*** 獲取對象的元數據** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @return*/public ObjectStat statObject(String bucketName, String objectName, SecretKey secretKey) throws Exception {boolean flag = bucketExists(bucketName);if (flag) {try {if (null != secretKey) {return minioClient.statObject(bucketName, objectName, ServerSideEncryption.withCustomerKey(secretKey));}return minioClient.statObject(bucketName, objectName);} catch (Exception e) {}}return null;}/*** 刪除一個對象** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱*/public boolean removeObject(String bucketName, String objectName) throws Exception {boolean flag = bucketExists(bucketName);if (flag) {minioClient.removeObject(bucketName, objectName);return true;}return false;}/*** 分享。** @param bucketName 存儲桶名稱* @param objectName 存儲桶里的對象名稱* @param expires 失效時間(以秒為單位),默認是7天,不得大于七天* @return*/public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {boolean flag = bucketExists(bucketName);if (flag) {if (null == expires) {expires = DEFAULT_EXPIRY_TIME;}if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {throw new RuntimeException("expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);}try {return minioClient.getPresignedObjectUrl(Method.GET, bucketName, objectName, expires, null);} catch (Exception e) {e.printStackTrace();}}return null;}/*** 獲取一個臨時可以上傳的url** @param bucketName* @param objectName* @return* @throws Exception*/public String presignedPutObject(String bucketName, String objectName) throws Exception {return minioClient.presignedPutObject(bucketName, objectName);}/*** 列出某個存儲桶中的所有對象** @param bucketName* @param objectNamePrefix 前綴* @return* @throws Exception*/public List<ComposeSource> listObjectsSource(String bucketName, String objectNamePrefix) throws Exception {List<ComposeSource> sources = new ArrayList<>();Iterable<Result<Item>> results = minioClient.listObjects(bucketName, objectNamePrefix);for (Result<Item> result : results) {Item item = result.get();ComposeSource source = new ComposeSource(bucketName, item.objectName());sources.add(source);}return sources;}/*** 文件合并** @param bucketName* @param objectName* @param sources* @param secretKey* @throws Exception*/public void composeObject(String bucketName, String objectName, List<ComposeSource> sources, SecretKey secretKey) throws Exception {if (null != secretKey) {minioClient.composeObject(bucketName, objectName, sources, null, ServerSideEncryption.withCustomerKey(secretKey));}minioClient.composeObject(bucketName, objectName, sources, null, null);for (ComposeSource source : sources) {minioClient.removeObject(source.bucketName(), source.objectName());}}}service 方法實現文件切割
實現思路
- 判斷文件大小是否需要分片上傳
-?生成每個分片上傳的minio地址, 前端直接調用對應的地上上傳分片
- 前端上傳完所有分片之后, 調用文件合并接口完成大文件上傳
/*** 文件分割** @param md5* @param fileSize* @return* @throws Exception*/ public JSONObject partInitUpload(String md5, double fileSize) throws Exception {// 存儲桶名稱String bucketName = Constants.FILE_CAT_BUCKET_NAME;minioUtil.makeBucket(bucketName);String username = ThreadLocalContextHolder.getCurrentUsername();JSONObject jsonObject = new JSONObject(true);// 判斷文件大小, 是否需要切割if (Constants.FILE_CAT_SIZE > fileSize) {return null;}// 判斷需要切割多少片int partSize = (int) Math.ceil(fileSize / Constants.FILE_CAT_FILE_PART);jsonObject.put("count", partSize);JSONArray uploadInfos = new JSONArray();for (long i = 0; i < partSize; i++) {JSONObject uploadInfo = new JSONObject();String objectName = username + "/" + md5 + "_" + i;ObjectStat statObject = minioUtil.statObject(bucketName, objectName, null);if (statObject != null && statObject.length() > 0) {continue;}// 獲取每一片文件的上傳地址String uploadUrl = minioUtil.presignedPutObject(bucketName, objectName);uploadInfo.put("part", i);uploadInfo.put("url", uploadUrl);uploadInfos.add(uploadInfo);}jsonObject.put("uploadInfos", uploadInfos);return jsonObject; }/*** 文件合并** @param md5* @param fileSize* @param fileName* @param folderId* @param diskType* @return* @throws Exception*/ public FileStorage composeFilePart(String md5, double fileSize, String fileName, String folderId, DiskType diskType) throws Exception {// 存儲桶 名稱String bucketName = Constants.FILE_CAT_BUCKET_NAME;String username = ThreadLocalContextHolder.getCurrentUsername();String objectName = username + "/" + md5;List<ComposeSource> composeSources = minioUtil.listObjectsSource(bucketName, objectName);int partSize = (int) Math.ceil(fileSize / Constants.FILE_CAT_FILE_PART);if (null != composeSources && partSize == composeSources.size()) {String randomCode = getRandomCode();String extension = FilenameUtils.getExtension(fileName);objectName = diskType + "/" + username + "/" + Constants.DATA_YEAR_MONTH.format(new Date()) + "/" + randomCode + "." + extension;bucketName = ThreadLocalContextHolder.getCurrentEcode();// 判斷文件是否需要加密存儲SecretKey secretKey = minioConfig.getSecretKey();minioUtil.composeObject(bucketName, objectName, composeSources, secretKey);FileStorage fileStorage = new FileStorage();// todo// 存文件相關信息return fileStorageRepository.save(fileStorage);}return null; }關注個人公眾號
總結
以上是生活随笔為你收集整理的minio文件加密/文件切割合并的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信重磅功能上线!传文件又快又安全
- 下一篇: VSTO | 零基础开发个人专属PPT导