S3FileService.java 11 KB

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