1. 先搭建好ftp文件系统

2. 在工程中引入jar

<dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
        </dependency>

3. 踩过的坑

3.1 changeWorkingDirectory(remotePath)执行该方法时总是切换ftp目录失败

  1. 解决方案注意此处的remotePath是相对路径,如果文件是在ftp服务器的根路径下放着,则remotePath="./" (注意一定要有点"."); 如果在ftp服务器的子路径,则remotePath="./文件夹1/"

3.2 FTPFile[] fs = ftp.listFiles()在服务器中获取结果总是为空

  1. 解决方案:请检查是否在执行changeWorkingDirectory(remotePath)方法前执行ftp.enterLocalPassiveMode(); 如果没有,一定要加上!!!!!
  2. 原因
    (1)这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
    (2)在FTP服务中,涉及到客户端和服务器端的连接,连接就会涉及到端口的打开问题;
    (3)端口的打开中,又涉及到主动模式和被动模式。主动模式:客户端开放端口给服务端用;被动模式:服务端开放端口给客户端用。由于很多客户端在防火墙内,开放端口给服务器端用比较困难。所以用被动模式的时候比较多。
    (4)如果涉及到了内网、局域网等环境时,出现FTP连接问题,也可以考虑是否是因为连接模式引起的。

3.3 在win环境下解析excel正常,但在linux环境下,读取某个excel时报错: java.io.IOException: Failed to read zip entry source…Caused by: java.util.zip.ZipException: invalid entry size (expected 438 but got 436 bytes)

  1. 解决方案:在连接FTP服务器成功之后,加入ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  2. 原因
    (1)FTP文件模式有两种:ascii和binary,当读取以下文件时,FTP文件模式要使用binary:
    image files (e.g. .jpg, .bmp, .png)
    sound files (e.g. .mp3, .avi, .wma)
    video files (eg. .flv, .mkv, .mov, .mp4),
    archive files (e.g. .zip, .rar, .tar)
    other files (e.g. .exe, .doc, .xls, .pdf, etc.)
    (2)当传输text文本时才使用 FTP.ASCII_FILE_TYPE 一般来说能使用简单文件编辑器打开的文件,如 Notepad, nano, or pico 是文本文件,但当文件中有中文日文这种,ascii不支持的字符时还是要使用BINARY_FILE_TYPE
    3.4 java连接FTP服务器循环处理多个文件时,第二次执行ftpClient.retrieveFileStream(fileName)时,总是为null

解决办法:

InputStream inputStream = ftpClient.retrieveFileStream(ftpFile.getName());
   ...
   ...
   //注意:inputStream都要close之后才能重新调用retrieveFileStream方法
   //下边两行代码代码至关重要,不然会报空!
   inputStream.close();
   ftpClient.completePendingCommand();