一,场景:其他平台往FTP服务器传输文件,我方读取文件。
二,原因:会存在,敌方未写完,我就读取了,导致读到文件数据不全。但是,敌方未写完,文件会上传吗?实际是地方数据写完了,在上传的过程中,文件有了,数据没上传完,我读的数据不全。
同样,我方文件上传,可能没传完,敌方就读取了,会造成同样的问题。
三,处理逻辑
我要保证敌方数据确实上传完了,我再下载,我方数据确实上传完了,敌方才能读取。
通过另外一个,同文件名,不同后缀的文件。
3.1,我方下载,敌方要上传文件1.DAT,上传完成后(应该是数据上传完成),再上传文件1.CTL。我方读取时,先判断是否存在1.CTL,存在说明1.DAT文件数据上传完整。
3.2,我方上传,先上传DAT,再上传CTL
四,代码
我方下载
@Override
public Boolean insertOversea() throws Exception {
logger.info("开始执行oversea落中间表..........");
long startTimeOversea = System.currentTimeMillis();
if (!redisUtils.isLock("insertOversea")) {
logger.info("oversea落中间表-未被锁定...");
redisUtils.lock("insertOversea");
Date now = new Date();
FtpUtil ftpUtil = new FtpUtil(overseaInformation.getProperty("ftp.ip"), Integer.parseInt(overseaInformation.getProperty("ftp.port")), overseaInformation.getProperty("ftp.name"),
overseaInformation.getProperty("ftp.pwd"));
try {
ftpUtil.open();
List<String> fileNames = ftpUtil.getFileNameList("SAP_WMS/OVERSEADN/Unhandled");
logger.info("fileNames={}", fileNames);
if (fileNames == null || fileNames.isEmpty()) {
return true;
}
for (String fileName : fileNames) {
String name = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
String nameOversea = name.substring(1, name.length());
String suffer = fileName.substring(fileName.indexOf(".") + 1, fileName.length());
if (suffer.equals("CTL")) {
continue;
}
String nameCTL = name.substring(0, name.indexOf(".")) + CTL_FILE_SUFFIX;
String fileNameCTL = fileName.substring(0, fileName.lastIndexOf(".")) + CTL_FILE_SUFFIX;
if (!fileNames.contains(fileNameCTL)) {
logger.info("不存在ctl文件!");
continue;
}
try {
ftpUtil.download(fileName, DOWN_NAME + name);
List<String> contents = ftpUtil.analysis(fileName);
long startTimeToEntity = System.currentTimeMillis();
List<OverseaEntity> overseas = this.conversionToObject(nameOversea, contents, now);
long endTimeToEntity = System.currentTimeMillis();
logger.info("解析文件:" + nameOversea + ",封装数据时间: " + (endTimeToEntity - startTimeToEntity) + "ms");
if (overseas == null || overseas.size() < 1) {
continue;
}
// 把批量的方式改成单次
// overseaMapper.insertList(overseas);
long startTimeLuoDi = System.currentTimeMillis();
for (OverseaEntity oversea : overseas) {
OverseaEntity entity = new OverseaEntity();
entity.setItem(oversea.getItem());
entity.setFileName(nameOversea);
OverseaEntity res = overseaMapper.selectOne(entity);
if (res == null) {
overseaMapper.insert(oversea);
}
}
long endTimeLuoDi = System.currentTimeMillis();
logger.info("文件:" + nameOversea + ",数据落地时间: " + (endTimeLuoDi - startTimeLuoDi) + "ms");
ftpUtil.move(fileName, "SAP_WMS/OVERSEADN/Handled" + name);
ftpUtil.move(fileNameCTL, "SAP_WMS/OVERSEADN/Handled" + nameCTL);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof ServiceException) {
throw e;
} else {
ftpUtil.move(fileName, "SAP_WMS/OVERSEADN/Error" + name);
ftpUtil.move(fileNameCTL, "SAP_WMS/OVERSEADN/Handled" + nameCTL);
continue;
}
}
}
long endTimeOversea = System.currentTimeMillis();
logger.info("落接口表时间: " + (endTimeOversea - startTimeOversea) + "ms");
redisUtils.unLock("insertOversea");
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
redisUtils.unLock("insertOversea");
ftpUtil.close();
}
} else {
logger.info("oversea落中间表-已被锁定...");
}
return true;
}
我方上传
// 必须先上传DAT文件,再上传CTL文件
String ftpDirectory = receiptInformation.getProperty("receipt.ftp.unhandled");
Boolean result = ftpUtil.upload(localDirectoryAndFileName, fileName, ftpDirectory);
if (!result) {
logger.error("上传DAT失败!");
}
String localDirectoryAndFileNameCTL = localFilePath + fileNameCTL;
Boolean resultCTL = ftpUtil.upload(localDirectoryAndFileNameCTL, fileNameCTL, ftpDirectory);
if (!resultCTL) {
logger.error("上传CTL失败!");
}