瀏覽代碼

1.解析后文件存储目录增加文件类型级别
2.压缩上传文件业务优化

tl 6 月之前
父節點
當前提交
2ca8b0f4f2

+ 21 - 41
cpp-admin/src/main/java/com/cpp/web/service/datafactory/SftpFileParsing.java

@@ -22,14 +22,13 @@ import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.time.DateFormatUtils;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.io.*;
 import java.lang.reflect.Field;
+import java.nio.file.Files;
 import java.util.*;
 import java.util.stream.Collectors;
-import java.util.zip.ZipOutputStream;
 
 /**
  * ftp文件解析主类
@@ -122,7 +121,6 @@ public class SftpFileParsing {
             ParsingInterface parsingInterface = parsingInterfaceMap.get(parsingType.getFileType().name() + "Parsing");
             parsingInterface.activationParsingConf();//初始化解析配置
             for (ElectricField electricField : channelElectricFields) {
-
                 String ftpUrl = electricField.getSftpUrl();
                 List<String> fileNames = sftp.ls(ftpUrl).stream().filter(f -> f.contains(parsingType.getFileName())).collect(Collectors.toList());
                 if (fileNames.size() > 0) {
@@ -144,13 +142,12 @@ public class SftpFileParsing {
                             parsingLog.setStationCode(electricField.getStationCode());
                             if (parsingResultDto.getStatus().equals("fail")) {
                                 try {
-                                    File failFileDir = new File(PARSING_FILE_FAIL_DIR.getPath() + File.separator + DateFormatUtils.format(now, "yyyy-MM-dd") + File.separator + electricField.getStationCode());
+                                    File failFileDir = new File(PARSING_FILE_FAIL_DIR.getPath() + File.separator + DateFormatUtils.format(now, "yyyy-MM-dd") + File.separator + electricField.getStationCode() + File.separator + parsingType.getFileType().name());
                                     File failFile = new File(failFileDir.getPath() + File.separator + fileName);
                                     if (failFile.exists()) {
                                         failFile.delete();
                                         log.error("已有过解析失败文件,错误文件将覆盖!场站编号:{},文件名称:{}", electricField.getStationCode(), fileName);
                                     }
-
                                     ParsingFileUtil.move(file.getAbsolutePath(), failFileDir.getAbsolutePath(), true);
                                 } catch (IOException e) {
                                     log.error("解析文件失败后文件移动失败!场站编号:{},文件名称:{}", electricField.getStationCode(), fileName, e);
@@ -158,21 +155,16 @@ public class SftpFileParsing {
                                 }
                                 file.delete();//失败删除本地文件,等待下次下载
                                 parsingLog.setParsingFileStatus("失败");
-
-
                                 LogUtil.info(DataSourcesEnum.E3, AlarmEnum.E4, LogUtil.format("无法解析场站端文件:{}", fileName), electricField.getStationCode());
-
                             } else {
                                 sftp.delFile(ftpUrl + "/" + fileName);//成功删除ftp上的文件
-
                                 try {
-                                    File successFileDir = new File(PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + DateFormatUtils.format(now, "yyyy-MM-dd") + File.separator + electricField.getStationCode());
+                                    File successFileDir = new File(PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + DateFormatUtils.format(now, "yyyy-MM-dd") + File.separator + electricField.getStationCode() + File.separator + parsingType.getFileType().name());
                                     File successFile = new File(successFileDir.getPath() + File.separator + fileName);
                                     if (successFile.exists()) {
                                         successFile.delete();
                                         log.error("已有过解析成功文件,成功文件将覆盖!场站编号:{},文件名称:{}", electricField.getStationCode(), fileName);
                                     }
-
                                     ParsingFileUtil.move(file.getAbsolutePath(), successFileDir.getAbsolutePath(), true);
                                 } catch (IOException e) {
                                     log.error("解析文件成功后文件移动失败!场站编号:{},文件名称:{}", electricField.getStationCode(), fileName, e);
@@ -194,7 +186,6 @@ public class SftpFileParsing {
 //            });
 
         }
-
         parsingLogService.saveBatch(parsingLogs);
     }
 
@@ -249,26 +240,27 @@ public class SftpFileParsing {
 
         String dirYesToday = DateFormatUtils.format(new Date(System.currentTimeMillis() - 86400000L), "yyyy-MM-dd");
         for (SftpChannel sftpChannel : sftpChannels) {
-
             List<ElectricField> channelElectricFields = electricFields.stream().filter(e -> e.getSftpChanelId() != null && e.getSftpChanelId().equals(sftpChannel.getId())).collect(Collectors.toList());
-
             if (channelElectricFields.size() > 0) {
                 SftpConfig sftpConfig = createSftp(sftpChannel);
                 if (sftpConfig.getSftp() != null) {
+                    String failSrc = PARSING_FILE_FAIL_DIR.getPath() + File.separator + dirYesToday;
+                    String successSrc = PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + dirYesToday;
                     for (ElectricField channelElectricField : channelElectricFields) {
-                        File failFileDir = new File(PARSING_FILE_FAIL_DIR.getPath() + File.separator + dirYesToday + File.separator + channelElectricField.getStationCode());
+                        File failFileDir = new File(failSrc + File.separator + channelElectricField.getStationCode());
                         if (failFileDir.exists()) {
-                            String zipPath = ZipUtil.zip(failFileDir.getAbsolutePath(), PARSING_FILE_FAIL_DIR.getPath() + File.separator + dirYesToday + "_FAIL.zip");
-                            if (zipPath != null && new File(zipPath).exists()) {
-                                upload(sftpConfig.getSftp(), channelElectricField.getSftpBackupUrl(), zipPath);
+                            String zipFileName = dirYesToday + "_" + channelElectricField.getStationCode() + "_FAIL.zip";
+                            String zipPath = PARSING_FILE_FAIL_DIR.getPath() + File.separator + zipFileName;
+                            if (ZipUtil.zip(failFileDir.getAbsolutePath(), zipPath) && new File(zipPath).exists()) {
+                                upload(sftpConfig.getSftp(), channelElectricField.getSftpBackupUrl(), zipPath, zipFileName);
                             }
                         }
-
-                        File successFileDir = new File(PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + dirYesToday + File.separator + channelElectricField.getStationCode());
+                        File successFileDir = new File(successSrc + File.separator + channelElectricField.getStationCode());
                         if (successFileDir.exists()) {
-                            String zipPath = ZipUtil.zip(successFileDir.getAbsolutePath(), PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + dirYesToday + "_SUCCESS.zip");
-                            if (zipPath != null && new File(zipPath).exists()) {
-                                upload(sftpConfig.getSftp(), channelElectricField.getSftpBackupUrl(), zipPath);
+                            String zipFileName = dirYesToday + "_" + channelElectricField.getStationCode() + "_SUCCESS.zip";
+                            String zipPath = PARSING_FILE_SUCCESS_DIR.getPath() + File.separator + zipFileName;
+                            if (ZipUtil.zip(successFileDir.getAbsolutePath(), zipPath) && new File(zipPath).exists()) {
+                                upload(sftpConfig.getSftp(), channelElectricField.getSftpBackupUrl(), zipPath, zipFileName);
                             }
                         }
                     }
@@ -289,27 +281,16 @@ public class SftpFileParsing {
     private void upload(
             Sftp sftp,
             String destPathName,
-            String srcName
+            String srcName,
+            String fileName
     ) {
-        FileInputStream fis = null;
-        try {
-            fis = new FileInputStream(srcName);
+        try (FileInputStream fis = new FileInputStream(srcName)) {
             File file = new File(srcName);
-            sftp.getClient().put(fis, destPathName + "/" + file.getName());
-            //有没删掉文件的情况,怀疑是文件没有传输完成导致的文件被占用,静止一秒后再删除试试
-            Thread.sleep(1000L);
-            file.delete();
+            sftp.getClient().put(fis, destPathName + "/" + fileName);
+            fis.close();
+            Files.deleteIfExists(file.toPath());
         } catch (Exception e) {
             log.error("上传备份文件异常", e);
-
-        } finally {
-            try {
-                if (fis != null) {
-                    fis.close();
-                }
-            } catch (IOException e) {
-                log.error("关闭文件流异常", e);
-            }
         }
     }
 
@@ -334,6 +315,5 @@ public class SftpFileParsing {
                 sshSession.disconnect();
             }
         }
-
     }
 }

+ 69 - 100
cpp-admin/src/main/java/com/cpp/web/utils/ZipUtil.java

@@ -9,138 +9,107 @@ import java.util.zip.ZipOutputStream;
 @Slf4j
 public class ZipUtil {
 
-    private static final int  BUFFER_SIZE = 2 * 1024;
+    private static final int BUFFER_SIZE = 2 * 1024;
 
 
     /**
-     * 压缩
+     * 压缩目录到ZIP文件
      *
-     * @param path
-     * @return
+     * @param sourceDirPath 源目录路径
+     * @param zipFilePath   目标ZIP文件路径
+     * @return 压缩成功返回true,否则返回false
      */
-    public static String zip(String path, String zipPath) {
-        FileOutputStream fos = null;
-        try {
-
-            fos = new FileOutputStream(new File(zipPath));
-            if (toZip(path, fos, true)) {
-                //压缩成功后删除目录
-                delFile(new File(path));
-                log.info("压缩成功,将【" + path + "]目录删除");
-            }
-
-            return zipPath;
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-            return null;
+    public static boolean zip(String sourceDirPath, String zipFilePath) {
+        File sourceDir = new File(sourceDirPath);
+        if (!sourceDir.isDirectory()) {
+            log.error("源路径不是一个有效的目录:" + sourceDirPath);
+            return false;
         }
 
-    }
-
-    //递归删除法
-    public static boolean delFile(File file) {
-        if (file.isDirectory()) {
-            File[] files = file.listFiles();
-            for (File f : files) {
-                delFile(f);
+        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
+             ZipOutputStream zos = new ZipOutputStream(fos)) {
+            if (toZip(sourceDirPath, zos, true)) {
+                // 注意:删除目录的操作应该非常谨慎,这里只是示例
+                // 在实际应用中,应该由调用者决定是否删除源目录
+                delFile(sourceDir);
+                // log.info("压缩成功,已删除【" + sourceDirPath + "】目录");
+                log.info("压缩成功");
+                return true;
+            } else {
+                log.error("压缩失败:无法压缩【" + sourceDirPath + "】目录");
+                return false;
             }
+        } catch (IOException e) {
+            log.error("压缩过程中发生错误:", e);
+            return false;
         }
-        return file.delete();
     }
 
     /**
-     * 目录转为zip包
+     * 目录转为zip包(静态方法)
      *
-     * @param srcDir
-     * @param out
-     * @param KeepDirStructure
-     * @return
-     * @throws RuntimeException
+     * @param srcDir           源目录路径
+     * @param zos              ZIP输出流
+     * @param keepDirStructure 是否保留原来的目录结构
+     * @return 压缩成功返回true,否则返回false
+     * @throws RuntimeException 如果发生无法处理的异常,则抛出运行时异常
      */
-    public static Boolean toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {
-
-        long start = System.currentTimeMillis();
-        ZipOutputStream zos = null;
+    private static boolean toZip(String srcDir, ZipOutputStream zos, boolean keepDirStructure) {
+        File sourceFile = new File(srcDir);
         try {
-            zos = new ZipOutputStream(out);
-            File sourceFile = new File(srcDir);
-            compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
-            long end = System.currentTimeMillis();
-            log.info("前一日已上报文件压缩完成,耗时:" + (end - start) + " ms");
+            compress(sourceFile, zos, sourceFile.getName(), keepDirStructure);
             return true;
-        } catch (Exception e) {
-            log.info("已上报文件压缩错误!!!", e);
+        } catch (IOException e) {
+            log.error("已上报文件压缩错误!!!", e);
             return false;
-        } finally {
-            if (zos != null) {
-                try {
-                    zos.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
         }
-
     }
 
     /**
      * 递归压缩方法
      *
-     * @param sourceFile       源文件
-     * @param zos              zip输出流
-     * @param name             压缩后的名称
-     * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
-     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
-     * @throws Exception
+     * @param sourceFile       源文件或目录
+     * @param zos              ZIP输出流
+     * @param entryName        ZIP条目名称
+     * @param keepDirStructure 是否保留原来的目录结构
+     * @throws IOException 如果发生I/O错误,则抛出IOException
      */
-    private static void compress(File sourceFile, ZipOutputStream zos, String name,
-                                 boolean KeepDirStructure) throws Exception {
-        byte[] buf = new byte[BUFFER_SIZE];
+    private static void compress(File sourceFile, ZipOutputStream zos, String entryName, boolean keepDirStructure) throws IOException {
         if (sourceFile.isFile()) {
-            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
-            zos.putNextEntry(new ZipEntry(name));
-            // copy文件到zip输出流中
-            int len;
-            FileInputStream in = null;
-            try {
-                in = new FileInputStream(sourceFile);
-                while ((len = in.read(buf)) != -1) {
-                    zos.write(buf, 0, len);
-                }
-                // Complete the entry
-                zos.closeEntry();
-            } catch (Exception e) {
-                e.printStackTrace();
-            } finally {
-                if (in != null) {
-                    in.close();
+            zos.putNextEntry(new ZipEntry(entryName));
+            try (FileInputStream fis = new FileInputStream(sourceFile)) {
+                byte[] buffer = new byte[BUFFER_SIZE];
+                int len;
+                while ((len = fis.read(buffer)) != -1) {
+                    zos.write(buffer, 0, len);
                 }
             }
-
-        } else {
-            File[] listFiles = sourceFile.listFiles();
-            if (listFiles == null || listFiles.length == 0) {
-                // 需要保留原来的文件结构时,需要对空文件夹进行处理
-                if (KeepDirStructure) {
-                    // 空文件夹的处理
-                    zos.putNextEntry(new ZipEntry(name + "/"));
-                    // 没有文件,不需要文件的copy
+            zos.closeEntry();
+        } else if (sourceFile.isDirectory()) {
+            File[] files = sourceFile.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    String newName = keepDirStructure ? entryName + "/" + file.getName() : file.getName();
+                    compress(file, zos, newName, keepDirStructure);
+                }
+                if (keepDirStructure && files.length == 0) {
+                    zos.putNextEntry(new ZipEntry(entryName + "/"));
                     zos.closeEntry();
                 }
+            }
+        }
+    }
 
-            } else {
-                for (File file : listFiles) {
-                    // 判断是否需要保留原来的文件结构
-                    if (KeepDirStructure) {
-                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
-                        // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
-                        compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
-                    } else {
-                        compress(file, zos, file.getName(), KeepDirStructure);
-                    }
-                }
+    // 注意:delFile 方法已经被注释掉,因为它在实际应用中可能是一个危险的操作
+    // 如果您确实需要它,请确保在安全的上下文中使用,并且用户已经明确同意删除操作
+    public static boolean delFile(File file) {
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            for (File f : files) {
+                delFile(f);
             }
         }
+        return file.delete();
     }
 
 }