From 0b0f9d1853817d101592c647bfcb7ceedf8dd7cb Mon Sep 17 00:00:00 2001 From: wang Date: Wed, 22 Jul 2026 14:07:41 +0800 Subject: [PATCH] =?UTF-8?q?txt=E8=A7=A3=E6=9E=90=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataserviceyy/service/FtpSyncService.java | 17 ++++++----------- .../threecloud/dataserviceyy/util/FtpUtil.java | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java b/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java index 3f52d61..25a71b4 100644 --- a/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java +++ b/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java @@ -243,8 +243,9 @@ public class FtpSyncService { */ private boolean processLine(String line, FtpCityConfig city, Set existingIds, FTPClient ftp) throws Exception { - // 按分隔符拆分字段(老淮南FTP数据格式:※分隔) - String[] fields = line.split(properties.getFieldSeparator(), -1); + // 按分隔符拆分字段(*分隔,需转义正则特殊字符) + String separator = java.util.regex.Pattern.quote(properties.getFieldSeparator()); + String[] fields = line.split(separator, -1); if (fields.length < MIN_FIELD_COUNT) { logger.debug("【FTP行】字段数不足({}<{}),跳过: {}", fields.length, MIN_FIELD_COUNT, line); return false; @@ -300,22 +301,16 @@ public class FtpSyncService { String ossPath = FilePathUtil.buildOssPath(city.getCityCode(), callStartTime, recordFileName); // 下载录音文件(FTP路径:{ftp-record-dir}/{yyyyMMdd}/{filename}) - // 先切换到录音文件根目录,避免工作目录在别处导致下载失败 + // 使用绝对路径下载,避免切换目录导致的问题 String recordDir = city.getFtpRecordDir(); - // 去掉末尾斜杠,避免双斜杠 if (recordDir != null && recordDir.endsWith("/")) { recordDir = recordDir.substring(0, recordDir.length() - 1); } - logger.info("【FTP行】准备切换目录: {}", recordDir); - FtpUtil.changeDir(ftp, recordDir); - String remoteRecordPath = dateStr + "/" + recordFileName; - logger.info("【FTP行】准备下载录音: {}/{}", recordDir, remoteRecordPath); + String remoteRecordPath = recordDir + "/" + dateStr + "/" + recordFileName; + logger.info("【FTP行】准备下载录音: {}", remoteRecordPath); byte[] recordBytes = FtpUtil.downloadFile(ftp, remoteRecordPath); logger.info("【FTP行】下载录音: {} ({} 字节)", recordFileName, recordBytes.length); - // 下载完成后切回txt目录,继续处理下一个文件 - FtpUtil.changeDir(ftp, city.getFtpSourceDir()); - // 上传到OSS(获取可访问的URL) String ossUrl = fileUploadUtil.uploadWav(ossPath, recordFileName, recordBytes); logger.info("【FTP行】上传OSS: {}", ossUrl); diff --git a/src/main/java/com/threecloud/dataserviceyy/util/FtpUtil.java b/src/main/java/com/threecloud/dataserviceyy/util/FtpUtil.java index 397b9c0..0870e2d 100644 --- a/src/main/java/com/threecloud/dataserviceyy/util/FtpUtil.java +++ b/src/main/java/com/threecloud/dataserviceyy/util/FtpUtil.java @@ -88,29 +88,35 @@ public class FtpUtil { } /** - * 下载文件到本地字节数组 + * 下载文件到本地字节数组(自动完成FTP pending命令) * * @param ftp 已连接的FTPClient * @param remotePath 远程文件路径(绝对或相对于当前工作目录) * @return 文件字节内容 */ public static byte[] downloadFile(FTPClient ftp, String remotePath) throws IOException { - try (InputStream in = ftp.retrieveFileStream(remotePath); - ByteArrayOutputStream out = new ByteArrayOutputStream()) { + InputStream in = null; + try { + in = ftp.retrieveFileStream(remotePath); if (in == null) { throw new IOException("下载文件失败(无输入流): " + remotePath); } + ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[8192]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } - // 必须调用 completePendingCommand,否则后续操作会失败 + return out.toByteArray(); + } finally { + // 必须关闭流并调用 completePendingCommand,否则后续FTP操作会失败 + if (in != null) { + try { in.close(); } catch (IOException ignored) {} + } boolean ok = ftp.completePendingCommand(); if (!ok) { - throw new IOException("FTP下载未完成: " + remotePath); + logger.warn("FTP completePendingCommand 返回 false: {}", remotePath); } - return out.toByteArray(); } }