Explorar o código

Revert "优化上传视频接口,尝试,有问题直接回退"

This reverts commit 0e8b2750c9967c9b3cec9f7efe74bfa81e742eea.
liudongzhi hai 1 mes
pai
achega
b1fd66e5cb
Modificáronse 1 ficheiros con 81 adicións e 242 borrados
  1. 81 242
      alien-store/src/main/java/shop/alien/store/util/FileUploadUtil.java

+ 81 - 242
alien-store/src/main/java/shop/alien/store/util/FileUploadUtil.java

@@ -16,18 +16,10 @@ import shop.alien.util.common.VideoUtils;
 import shop.alien.util.file.FileUtil;
 
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
 import java.util.*;
-import java.util.concurrent.*;
-import java.util.stream.Collectors;
 
 /**
  * 二期-文件上传
@@ -126,7 +118,7 @@ public class FileUploadUtil {
     }
 
     /**
-     * 上传多个文件(性能优化版 - 并行处理 + 流式复制)
+     * 上传多个文件
      *
      * @param multipartRequest 多文件
      * @return List<String>
@@ -135,173 +127,82 @@ public class FileUploadUtil {
         try {
             log.info("FileUpload.uploadMoreFile multipartRequest={}", multipartRequest.getFileNames());
             Set<String> fileNameSet = multipartRequest.getMultiFileMap().keySet();
-            String uploadDir = this.uploadDir.replace("file:///", "").replace("\\", "/");
-            
-            // 如果只有一个文件,直接处理(避免线程池开销)
-            if (fileNameSet.size() == 1) {
-                return uploadMoreFileSequential(multipartRequest, fileNameSet, uploadDir);
-            }
-            
-            // 多个文件使用并行处理
-            List<CompletableFuture<List<String>>> futures = new ArrayList<>();
-            ExecutorService executor = createUploadExecutor();
-            
-            try {
-                for (String s : fileNameSet) {
-                    MultipartFile multipartFile = multipartRequest.getFileMap().get(s);
-                    CompletableFuture<List<String>> future = CompletableFuture.supplyAsync(() -> {
-                        return processSingleFile(multipartFile, uploadDir);
-                    }, executor);
-                    futures.add(future);
-                }
-                
-                // 等待所有任务完成并合并结果
-                List<String> filePathList = new ArrayList<>();
-                for (CompletableFuture<List<String>> future : futures) {
-                    try {
-                        filePathList.addAll(future.get());
-                    } catch (Exception e) {
-                        log.error("处理文件失败", e);
-                        throw new RuntimeException("文件处理失败: " + e.getMessage(), e);
+            List<String> filePathList = new ArrayList<>();
+            for (String s : fileNameSet) {
+                MultipartFile multipartFile = multipartRequest.getFileMap().get(s);
+                log.info("FileUpload.uploadMoreFile fileName={}", multipartFile.getOriginalFilename());
+                String uploadDir = this.uploadDir.replace("file:///", "").replace("\\", "/");
+                String prefix;
+                Map<String, String> fileNameAndType = FileUtil.getFileNameAndType(multipartFile);
+                //区分文件类型
+                if (imageFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/image";
+                    prefix = "image/";
+                    log.info("FileUpload.uploadMoreFile 获取到图片文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String imageFileName = fileNameAndType.get("name").replaceAll(",", "");
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + imageFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
+                    ;
+                } else if (videoFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/video/";
+                    prefix = "video/";
+                    //上传视频文件
+                    log.info("FileUpload.uploadMoreFile 获取到视频文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String videoFileName = fileNameAndType.get("name").replaceAll(",", "") + RandomCreateUtil.getRandomNum(6);
+                    String cacheVideoPath = copyFile(uploadDir, multipartFile);
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + videoFileName + "." + fileNameAndType.get("type")));
+                    //缓存视频截图使用
+                    File videoFile = new File(cacheVideoPath);
+                    //获取视频某帧截图
+                    log.info("FileUpload.uploadMoreFile 视频文件复制完毕, 获取第一秒图片 {}", videoFile.getName());
+                    String videoPath = videoUtils.getImg(uploadDir + videoFile.getName());
+                    log.info("FileUpload.uploadMoreFile 视频文件复制完毕, 图片位置 {}", videoPath);
+                    if (!videoPath.isEmpty()) {
+                        File videoImgFile = new File(videoPath);
+                        Map<String, String> videoImg = FileUtil.getFileNameAndType(videoImgFile);
+                        filePathList.add(aliOSSUtil.uploadFile(videoImgFile, prefix + videoFileName + "." + videoImg.get("type")));
+                        videoImgFile.delete();
+                        videoFile.delete();
+                    } else {
+                        throw new RuntimeException("视频截图失败");
                     }
+                } else if (voiceFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/voice";
+                    prefix = "voice/";
+                    log.info("FileUpload.uploadMoreFile 获取到语音文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String voiceFileName = fileNameAndType.get("name").replaceAll(",", "");
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + voiceFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
+                } else if (privacyFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/privacy/";
+                    prefix = "privacy/";
+                    log.info("FileUpload.uploadMoreFile 获取到隐私文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String privacyFileName = fileNameAndType.get("name").replaceAll(",", "");
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + privacyFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
+                } else if (pdfFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/pdf";
+                    prefix = "pdf/";
+                    log.info("FileUpload.uploadMoreFile 获取到PDF文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String pdfFileName = fileNameAndType.get("name").replaceAll(",", "");
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + pdfFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
+                } else if (ohterFileType.contains(fileNameAndType.get("type").toLowerCase())) {
+                    uploadDir += "/other/";
+                    prefix = "other/";
+                    log.info("FileUpload.uploadMoreFile 获取到其他文件准备复制 {} {} {}", uploadDir, prefix, multipartFile.getOriginalFilename());
+                    // 去除文件名中的逗号,避免URL拼接时被错误分割
+                    String otherFileName = fileNameAndType.get("name").replaceAll(",", "");
+                    filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + otherFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
                 }
-                
-                return filePathList;
-            } finally {
-                executor.shutdown();
             }
-        } catch (Exception e) {
-            log.error("FileUpload.uploadMoreFile ERROR Msg={}", e.getMessage(), e);
-            throw new RuntimeException(e);
-        }
-    }
-    
-    /**
-     * 顺序处理(单个文件时使用,避免线程池开销)
-     */
-    private List<String> uploadMoreFileSequential(MultipartRequest multipartRequest, Set<String> fileNameSet, String uploadDir) {
-        List<String> filePathList = new ArrayList<>();
-        for (String s : fileNameSet) {
-            MultipartFile multipartFile = multipartRequest.getFileMap().get(s);
-            filePathList.addAll(processSingleFile(multipartFile, uploadDir));
-        }
-        return filePathList;
-    }
-    
-    /**
-     * 处理单个文件
-     */
-    private List<String> processSingleFile(MultipartFile multipartFile, String baseUploadDir) {
-        List<String> filePathList = new ArrayList<>();
-        try {
-            log.info("FileUpload.processSingleFile fileName={}", multipartFile.getOriginalFilename());
-            String uploadDir = baseUploadDir;
-            String prefix;
-            Map<String, String> fileNameAndType = FileUtil.getFileNameAndType(multipartFile);
-            String fileType = fileNameAndType.get("type").toLowerCase();
-            
-            //区分文件类型
-            if (imageFileType.contains(fileType)) {
-                uploadDir += "/image";
-                prefix = "image/";
-                log.info("FileUpload.processSingleFile 获取到图片文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String imageFileName = fileNameAndType.get("name").replaceAll(",", "");
-                filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + imageFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
-                
-            } else if (videoFileType.contains(fileType)) {
-                uploadDir += "/video/";
-                prefix = "video/";
-                log.info("FileUpload.processSingleFile 获取到视频文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String videoFileName = fileNameAndType.get("name").replaceAll(",", "") + RandomCreateUtil.getRandomNum(6);
-                
-                // 优化:并行执行视频上传和文件复制(这两个操作互不依赖,可以并行)
-                CompletableFuture<String> uploadFuture = CompletableFuture.supplyAsync(() -> {
-                    return aliOSSUtil.uploadFile(multipartFile, prefix + videoFileName + "." + fileNameAndType.get("type"));
-                });
-                
-                // 复制文件用于截图(使用优化的流式复制)
-                String cacheVideoPath = copyFileOptimized(uploadDir, multipartFile);
-                File videoFile = new File(cacheVideoPath);
-                
-                // 等待上传完成(如果复制已完成,这里不会阻塞太久)
-                String videoUrl = uploadFuture.get();
-                filePathList.add(videoUrl);
-                
-                // 获取视频截图
-                log.info("FileUpload.processSingleFile 视频文件复制完毕, 获取第一秒图片 {}", videoFile.getName());
-                String videoPath = videoUtils.getImg(uploadDir + videoFile.getName());
-                log.info("FileUpload.processSingleFile 视频文件复制完毕, 图片位置 {}", videoPath);
-                
-                if (!videoPath.isEmpty()) {
-                    File videoImgFile = new File(videoPath);
-                    Map<String, String> videoImg = FileUtil.getFileNameAndType(videoImgFile);
-                    filePathList.add(aliOSSUtil.uploadFile(videoImgFile, prefix + videoFileName + "." + videoImg.get("type")));
-                    videoImgFile.delete();
-                    videoFile.delete();
-                } else {
-                    throw new RuntimeException("视频截图失败");
-                }
-                
-            } else if (voiceFileType.contains(fileType)) {
-                uploadDir += "/voice";
-                prefix = "voice/";
-                log.info("FileUpload.processSingleFile 获取到语音文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String voiceFileName = fileNameAndType.get("name").replaceAll(",", "");
-                filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + voiceFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
-                
-            } else if (privacyFileType.contains(fileType)) {
-                uploadDir += "/privacy/";
-                prefix = "privacy/";
-                log.info("FileUpload.processSingleFile 获取到隐私文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String privacyFileName = fileNameAndType.get("name").replaceAll(",", "");
-                filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + privacyFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
-                
-            } else if (pdfFileType.contains(fileType)) {
-                uploadDir += "/pdf";
-                prefix = "pdf/";
-                log.info("FileUpload.processSingleFile 获取到PDF文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String pdfFileName = fileNameAndType.get("name").replaceAll(",", "");
-                filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + pdfFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
-                
-            } else if (ohterFileType.contains(fileType)) {
-                uploadDir += "/other/";
-                prefix = "other/";
-                log.info("FileUpload.processSingleFile 获取到其他文件准备上传 {} {}", prefix, multipartFile.getOriginalFilename());
-                String otherFileName = fileNameAndType.get("name").replaceAll(",", "");
-                filePathList.add(aliOSSUtil.uploadFile(multipartFile, prefix + otherFileName + RandomCreateUtil.getRandomNum(6) + "." + fileNameAndType.get("type")));
-            }
-            
             return filePathList;
         } catch (Exception e) {
-            log.error("FileUpload.processSingleFile ERROR fileName={}, Msg={}", multipartFile.getOriginalFilename(), e.getMessage(), e);
-            throw new RuntimeException("处理文件失败: " + multipartFile.getOriginalFilename(), e);
+            log.error("FileUpload.uploadMoreFile ERROR Msg={}", e.getMessage());
+            throw new RuntimeException(e);
         }
     }
-    
-    /**
-     * 创建上传任务线程池
-     */
-    private ExecutorService createUploadExecutor() {
-        int corePoolSize = Math.min(Runtime.getRuntime().availableProcessors() * 2, 8);
-        int maxPoolSize = Math.min(Runtime.getRuntime().availableProcessors() * 4, 16);
-        return new ThreadPoolExecutor(
-                corePoolSize,
-                maxPoolSize,
-                60L,
-                TimeUnit.SECONDS,
-                new LinkedBlockingQueue<>(100),
-                new ThreadFactory() {
-                    private int count = 0;
-                    @Override
-                    public Thread newThread(Runnable r) {
-                        Thread t = new Thread(r);
-                        t.setName("file-upload-" + count++);
-                        return t;
-                    }
-                },
-                new ThreadPoolExecutor.CallerRunsPolicy()
-        );
-    }
 
     /**
      * 上传图片
@@ -349,92 +250,30 @@ public class FileUploadUtil {
     }
 
     /**
-     * 复制文件, 返回url链接(优化版 - 使用流式复制,避免一次性读取大文件)
+     * 复制文件, 返回url链接
      *
      * @param localFilePath 本地路径
      * @param file          文件
      * @return 访问url路径
      */
     private String copyFile(String localFilePath, MultipartFile file) {
-        return copyFileOptimized(localFilePath, file);
-    }
-    
-    /**
-     * 优化的文件复制方法 - 使用流式复制,避免一次性读取全部字节
-     * 对于大文件(如视频),性能提升显著
-     *
-     * @param localFilePath 本地路径
-     * @param file          文件
-     * @return 访问url路径
-     */
-    private String copyFileOptimized(String localFilePath, MultipartFile file) {
-        InputStream inputStream = null;
-        FileOutputStream outputStream = null;
-        ReadableByteChannel inputChannel = null;
-        FileChannel outputChannel = null;
-        
         try {
             File cacheFilePath = new File(localFilePath);
             if (!cacheFilePath.exists()) {
                 cacheFilePath.mkdirs();
             }
-            
-            String fileName = file.getOriginalFilename();
-            Path path = Paths.get(localFilePath, fileName);
+            String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.'));
+            log.info("FileUpload.copyFile fileName={}", fileName);
+            String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
+            log.info("FileUpload.copyFile fileType={}", fileType);
+            System.out.println(file.getOriginalFilename());
+            Path path = Paths.get(localFilePath, file.getOriginalFilename());
             Files.createDirectories(path.getParent());
-            
-            // 使用NIO的Channel进行高效复制(零拷贝技术)
-            File targetFile = path.toFile();
-            inputStream = file.getInputStream();
-            outputStream = new FileOutputStream(targetFile);
-            
-            // 将InputStream转换为ReadableByteChannel
-            inputChannel = Channels.newChannel(inputStream);
-            outputChannel = outputStream.getChannel();
-            
-            // 使用transferFrom进行高效复制,对于大文件性能更好
-            // 对于大文件,分块传输以避免内存问题
-            long transferred = 0;
-            long fileSize = file.getSize();
-            long chunkSize = 8 * 1024 * 1024; // 8MB chunks
-            
-            while (transferred < fileSize) {
-                long remaining = fileSize - transferred;
-                long toTransfer = Math.min(chunkSize, remaining);
-                transferred += outputChannel.transferFrom(inputChannel, transferred, toTransfer);
-            }
-            
-            return localFilePath + fileName;
+            Files.write(path, file.getBytes());
+            return localFilePath + file.getOriginalFilename();
         } catch (Exception e) {
-            log.error("FileUpload.copyFileOptimized ERROR Msg={}", e.getMessage(), e);
-            // 降级到传统方式
-            try {
-                Path path = Paths.get(localFilePath, file.getOriginalFilename());
-                Files.createDirectories(path.getParent());
-                // 使用缓冲流进行复制
-                try (InputStream is = file.getInputStream();
-                     FileOutputStream fos = new FileOutputStream(path.toFile())) {
-                    byte[] buffer = new byte[8192];
-                    int bytesRead;
-                    while ((bytesRead = is.read(buffer)) != -1) {
-                        fos.write(buffer, 0, bytesRead);
-                    }
-                }
-                return localFilePath + file.getOriginalFilename();
-            } catch (Exception ex) {
-                log.error("FileUpload.copyFileOptimized 降级方案也失败 Msg={}", ex.getMessage(), ex);
-                throw new RuntimeException("文件复制失败: " + ex.getMessage(), ex);
-            }
-        } finally {
-            // 关闭资源
-            try {
-                if (inputChannel != null) inputChannel.close();
-                if (outputChannel != null) outputChannel.close();
-                if (inputStream != null) inputStream.close();
-                if (outputStream != null) outputStream.close();
-            } catch (Exception e) {
-                log.warn("关闭文件流失败", e);
-            }
+            log.error("FileUpload.copyFile ERROR Msg={}", e.getMessage());
+            return e.getMessage();
         }
     }