FTP下载的文件处理报错:java.io.IOException: central directory is empty, can't expand corrupt archive.

一、问题来源

  最近做一个海安项目,不同网域之间数据需要通过FTP摆渡文件的形式同步,因此代码就涉及到FTP文件压缩上传、下载解压的操作。windows本地开发环境对文件下载解压没有问题,发布linux个别文件报如下错误:

org.apache.tools.ant.BuildException: Error while expanding /opt/opsmgr/web/components/tomcat85linux64.2/webapps/ctm01favorite/WEB-INF/classes/download/1648798558_zap.zip
java.io.IOException: central directory is empty, can't expand corrupt archive.
        at org.apache.tools.ant.taskdefs.Expand.expandFile(Expand.java:206)
        at org.apache.tools.ant.taskdefs.Expand.execute(Expand.java:148)
        at com.hikvision.js.ctm01favorite.utils.CompressUtils.decompressionZip(CompressUtils.java:46)
        at com.hikvision.js.ctm01favorite.task.ScheduledTasks.handleZipFile(ScheduledTasks.java:123)
        at com.hikvision.js.ctm01favorite.task.ScheduledTasks.lambda$ftpDataReceive$1(ScheduledTasks.java:83)
        at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:67)
        at com.hikvision.starfish.log.business.async.BusLogRunnable.run(BusLogRunnable.java:33)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.io.IOException: central directory is empty, can't expand corrupt archive.
        at org.apache.tools.zip.ZipFile.populateFromCentralDirectory(ZipFile.java:459)
        at org.apache.tools.zip.ZipFile.<init>(ZipFile.java:215)
        at org.apache.tools.ant.taskdefs.Expand.expandFile(Expand.java:184)
        ... 9 common frames omitted

排查发现报错的就是固定的那几个文件,本地windows环境检查发现文件状态正常,没有损坏的情况。

二、解决方法

  FTP文件下载时设置以字节的方式进行传输,ftpClient.setFileType(FTP.BINARY_FILE_TYPE);完整代码如下:

public boolean downloadFileNew(String pathname, String filename, String localpath, FTPClient ftpClient) {
        boolean flag = false;
        OutputStream os = null;
        try {
            logger.info("开始下载文件");
            // 切换FTP目录
            boolean changeFlag = ftpClient.changeWorkingDirectory(pathname);
            logger.info("changeFlag==" + changeFlag);

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setRemoteVerificationEnabled(false);
            // 查看有哪些文件夹 以确定切换的ftp路径正确
            String[] a = ftpClient.listNames();
            logger.info(a[0]);

            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    File localFile = new File(localpath + "/" + file.getName());
                    os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            //ftpClient.logout();
            flag = true;
            logger.info("下载文件成功");
        } catch (Exception e) {
            logger.error("下载文件失败", e);
        } finally {
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

问题解决。

三、总结

  部分文件上传时采用的方式是二进制方式,那么下载如果不采用二进制方式下载可能会出现问题。因此FTP文件操作尽量文件类型都设置成二进制类型。

posted @ 2022-04-19 17:23  莫等、闲  阅读(732)  评论(0编辑  收藏  举报