S3FileService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package com.fdkankan.fyun.s3;
  2. import cn.hutool.core.collection.CollUtil;
  3. import com.amazonaws.services.s3.AmazonS3;
  4. import com.amazonaws.services.s3.model.*;
  5. import com.fdkankan.fyun.constant.FYunConstants;
  6. import com.fdkankan.fyun.constant.FYunTypeEnum;
  7. import com.fdkankan.fyun.face.AbstractFYunFileService;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  13. import org.springframework.stereotype.Component;
  14. import org.springframework.util.ObjectUtils;
  15. import java.io.*;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.stream.Collectors;
  20. @Component
  21. @ConditionalOnProperty(name = "fyun.type",havingValue = "aws")
  22. public class S3FileService extends AbstractFYunFileService {
  23. private Logger log = LoggerFactory.getLogger(this.getClass().getName());
  24. @Autowired
  25. private AmazonS3 s3;
  26. @Override
  27. public String uploadFile(String bucket, byte[] data, String remoteFilePath){
  28. try {
  29. ObjectMetadata metadata = new ObjectMetadata();
  30. PutObjectRequest request = new PutObjectRequest(bucket, remoteFilePath, new ByteArrayInputStream(data), metadata);
  31. request.withCannedAcl(CannedAccessControlList.PublicRead);
  32. s3.putObject(request);
  33. } catch (Exception e) {
  34. log.error("s3上传文件失败", e);
  35. }
  36. return null;
  37. }
  38. @Override
  39. public String uploadFile(String bucket, String filePath, String remoteFilePath){
  40. return uploadFile(bucket, filePath, remoteFilePath,null);
  41. }
  42. @Override
  43. public String uploadFile(String bucket, String filePath, String remoteFilePath,Map<String, String> headers){
  44. try {
  45. File file = new File(filePath);
  46. if (!file.exists()) {
  47. log.error("要上传的文件不存在:" + filePath);
  48. return null;
  49. }
  50. // 设置文件并设置公读
  51. ObjectMetadata metadata = new ObjectMetadata();
  52. if (filePath.contains(".jpg")) {
  53. metadata.setContentType("image/jpeg");
  54. }
  55. if (filePath.contains(".png")) {
  56. metadata.setContentType("image/png");
  57. }
  58. if(org.apache.commons.lang3.ObjectUtils.isNotEmpty(headers)){
  59. for (Map.Entry<String, String> header : headers.entrySet()) {
  60. metadata.setHeader(header.getKey(),header.getValue());
  61. }
  62. }
  63. PutObjectRequest request = new PutObjectRequest(bucket, remoteFilePath, file);
  64. request.withCannedAcl(CannedAccessControlList.PublicRead);
  65. request.withMetadata(metadata);
  66. // 上传文件
  67. PutObjectResult putObjectResult = s3.putObject(request);
  68. if (StringUtils.isNotEmpty(putObjectResult.getETag())) {
  69. log.info("s3上传文件成功:" + remoteFilePath);
  70. }
  71. } catch (Exception e) {
  72. log.error("文件上传失败:{}",filePath);
  73. e.printStackTrace();
  74. }
  75. return null;
  76. }
  77. @Override
  78. public String uploadFileByCommand(String bucket, String filePath, String remoteFilePath){
  79. try {
  80. String optType = new File(filePath).isDirectory() ? "folder" : "file";
  81. String command = String.format(FYunConstants.UPLOAD_SH, bucket, filePath, remoteFilePath, FYunTypeEnum.AWS.code(), optType);
  82. log.info("开始上传文件, ossPath:{}, srcPath:{}", remoteFilePath, filePath);
  83. callshell(command);
  84. } catch (Exception e) {
  85. log.error("上传文件失败, ossPath:{}, srcPath:{}", remoteFilePath, filePath);
  86. e.printStackTrace();
  87. }
  88. return null;
  89. }
  90. @Override
  91. public void downloadFileByCommand(String bucket, String filePath, String remoteFilePath) {
  92. try {
  93. String optType = new File(filePath).isDirectory() ? "folder" : "file";
  94. String command = String.format(FYunConstants.DOWNLOAD_SH, bucket, filePath, remoteFilePath, FYunTypeEnum.LOCAL.code(), optType);
  95. log.info("开始上传文件, ossPath:{}, srcPath:{}", remoteFilePath, filePath);
  96. callshell(command);
  97. } catch (Exception e) {
  98. log.error("上传文件失败, ossPath:{}, srcPath:{}", remoteFilePath, filePath);
  99. e.printStackTrace();
  100. }
  101. }
  102. @Override
  103. public void deleteFile(String bucket, String remoteFilePath){
  104. if (remoteFilePath.startsWith("/")) {
  105. remoteFilePath = remoteFilePath.substring(1);
  106. }
  107. try {
  108. s3.deleteObject(bucket, remoteFilePath);
  109. } catch (Exception e) {
  110. log.error("s3删除文件失败,key=" + remoteFilePath, e);
  111. }
  112. }
  113. @Override
  114. public void deleteFolder(String bucket, String remoteFolderPath){
  115. try {
  116. int maxKeys = 200;
  117. String nextMaker = null;
  118. ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
  119. listObjectsRequest.setBucketName(bucket);
  120. listObjectsRequest.setPrefix(remoteFolderPath);
  121. listObjectsRequest.setMaxKeys(maxKeys);
  122. com.amazonaws.services.s3.model.ObjectListing objectListing;
  123. do {
  124. listObjectsRequest.setMarker(nextMaker);
  125. objectListing = s3.listObjects(listObjectsRequest);
  126. List<S3ObjectSummary> objectSummaries = objectListing.getObjectSummaries();
  127. List<DeleteObjectsRequest.KeyVersion> keys = objectSummaries.stream().map(summary -> new DeleteObjectsRequest.KeyVersion(summary.getKey())).collect(Collectors.toList());
  128. DeleteObjectsRequest multiObjectDeleteRequest = new DeleteObjectsRequest(bucket)
  129. .withKeys(keys).withQuiet(false);
  130. DeleteObjectsResult delObjRes = s3.deleteObjects(multiObjectDeleteRequest);
  131. int successfulDeletes = delObjRes.getDeletedObjects().size();
  132. log.info("删除aws文件成功,删除文件数;{}", successfulDeletes);
  133. nextMaker = objectListing.getNextMarker();
  134. } while (objectListing.isTruncated());
  135. } catch (Exception e) {
  136. log.error("删除was文件失败,path=" + remoteFolderPath, e);
  137. }
  138. }
  139. @Override
  140. public void uploadMulFiles(String bucket, Map<String, String> filepaths){
  141. try {
  142. for (Map.Entry<String, String> entry : filepaths.entrySet()) {
  143. uploadFile(bucket, entry.getKey(), entry.getValue(),null);
  144. }
  145. } catch (Exception e) {
  146. log.error("OSS批量上传文件失败!");
  147. }
  148. }
  149. @Override
  150. public List<String> listRemoteFiles(String bucket, String sourcePath) {
  151. List<String> keyList = new ArrayList<>();
  152. try {
  153. boolean flag = true;
  154. String nextMaker = null;
  155. ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
  156. listObjectsRequest.setBucketName(bucket);
  157. listObjectsRequest.setPrefix(sourcePath);
  158. listObjectsRequest.setMaxKeys(200);
  159. do {
  160. listObjectsRequest.setMarker(nextMaker);
  161. ObjectListing objectListing = s3.listObjects(listObjectsRequest);
  162. List<S3ObjectSummary> objectSummaries = objectListing.getObjectSummaries();
  163. List<String> collect = objectSummaries.stream().map(S3ObjectSummary::getKey).collect(Collectors.toList());
  164. if (CollUtil.isNotEmpty(collect)) {
  165. keyList.addAll(collect);
  166. }
  167. nextMaker = objectListing.getNextMarker();
  168. flag = objectListing.isTruncated();
  169. } while (flag);
  170. } catch (Exception e) {
  171. log.error("获取文件列表失败,path=" + sourcePath, e);
  172. e.printStackTrace();
  173. }
  174. return keyList;
  175. }
  176. @Override
  177. public void copyFileBetweenBucket(String sourceBucketName, String sourcePath, String targetBucketName, String targetPath){
  178. try {
  179. List<String> files = listRemoteFiles(sourceBucketName, sourcePath);
  180. if (ObjectUtils.isEmpty(files)) {
  181. log.error("源文件夹为空:{}", sourcePath);
  182. }
  183. files.stream().forEach(file -> {
  184. CopyObjectRequest request = new CopyObjectRequest(sourceBucketName, file, targetBucketName, file.replace(sourcePath, targetPath));
  185. request.withCannedAccessControlList(CannedAccessControlList.PublicRead);
  186. s3.copyObject(request);
  187. });
  188. } catch (Exception e) {
  189. log.error("列举文件目录失败,key=" + sourcePath);
  190. }
  191. }
  192. @Override
  193. public void copyFilesBetweenBucket(String sourceBucketName, String targetBucketName, Map<String, String> pathMap){
  194. if (ObjectUtils.isEmpty(pathMap)) {
  195. return;
  196. }
  197. try {
  198. for (Map.Entry<String, String> entry : pathMap.entrySet()) {
  199. copyFileBetweenBucket(sourceBucketName, entry.getKey(), targetBucketName, entry.getValue());
  200. }
  201. } catch (Exception e) {
  202. log.error("批量复制文件失败!");
  203. }
  204. }
  205. @Override
  206. public String getFileContent(String bucketName, String remoteFilePath){
  207. try {
  208. GetObjectRequest request = new GetObjectRequest(bucketName,remoteFilePath);
  209. S3Object object = s3.getObject(request);
  210. S3ObjectInputStream inputStream = object.getObjectContent();
  211. StringBuilder content = new StringBuilder();
  212. try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))){
  213. while (true) {
  214. String line = reader.readLine();
  215. if (line == null) break;
  216. content.append(line);
  217. }
  218. } catch (IOException e) {
  219. log.error("读取aws文件流失败", e);
  220. }
  221. object.close();
  222. return content.toString();
  223. } catch (Exception e) {
  224. log.error("获取文件内容失败:{}", remoteFilePath);
  225. return null;
  226. }
  227. }
  228. @Override
  229. public boolean fileExist(String bucket, String objectName) {
  230. try {
  231. return s3.doesObjectExist(bucket, objectName);
  232. } catch (Exception e) {
  233. log.error("判断文件是否存在失败:{}", objectName);
  234. return false;
  235. }
  236. }
  237. @Override
  238. public void downloadFile(String bucket, String remoteFilePath, String localPath) {
  239. try {
  240. File localFile = new File(localPath);
  241. if (!localFile.getParentFile().exists()) {
  242. localFile.getParentFile().mkdirs();
  243. }
  244. GetObjectRequest request = new GetObjectRequest(bucket, remoteFilePath);
  245. s3.getObject(request,new File(localPath));
  246. } catch (Throwable throwable) {
  247. log.error("文件下载失败:{}", remoteFilePath);
  248. throwable.printStackTrace();
  249. }
  250. }
  251. }