Recently, when using FTPClient to continuously read the contents of multiple files on ftp, we encountered two problems:
1. In the for loop, FTPClient can only read the contents of the first file. When reading the second file, it encountered NPE problems.
2. The program is locked.
Next, we will analyze the problems encountered and provide solutions:
Now use FTPClient to read two files a.txt and b.txt under the directory of ftp server / aaa/bbb /
Question 1:
Find the status of FTPClient's "replycode = 226 (226 converter complete.) data transmission completed before reading the first file through Debug. When reading the first file, the" replyCode=125 (125 data connection already open; converter starting.) data transmission is starting to be transferred, indicating that the first file has not been completely transferred, which causes InputStream to be null when reading the second file.
The solution is to execute ftpClient.completePendingCommand(); after reading the first file, and tell FTPClient that the data has been transferred.
Question 2:
ftpClient.completePendingCommand();; causes lock during read execution.
The solution ftpClient.completePendingCommand(); can only be executed after data transfer.
Finally, paste the complete code:
1 package com.shipc.demo.ftp; 2 3 import org.apache.commons.net.ftp.FTPClient; 4 import org.apache.commons.net.ftp.FTPFile; 5 import org.apache.commons.net.ftp.FTPReply; 6 7 import java.io.*; 8 9 /** 10 * @author shipc 2019/10/24 10:00 11 * @version 1.0 12 */ 13 public class TestFTP { 14 15 private FTPClient connectServer() { 16 FTPClient ftpClient = new FTPClient(); 17 ftpClient.setConnectTimeout(1000 * 60 * 30); 18 ftpClient.setControlEncoding("UTF-8"); 19 ftpClient.enterLocalPassiveMode(); //Set passive mode, file transfer port setting 20 try { 21 ftpClient.connect("172.17.0.16", 21); 22 ftpClient.login("ftp-user", "123456"); 23 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // Set file transfer mode to binary 24 final int replyCode = ftpClient.getReplyCode(); 25 if (!FTPReply.isPositiveCompletion(replyCode)) { 26 ftpClient.disconnect(); 27 } 28 } catch (Exception e) { 29 System.out.println(e.getMessage()); 30 } 31 return ftpClient; 32 } 33 34 private void readFiles(FTPClient ftpClient) throws IOException { 35 ftpClient.changeWorkingDirectory("/aaa/bbb"); 36 final FTPFile[] ftpFiles = ftpClient.listFiles(); 37 for (FTPFile ftpFile : ftpFiles) { 38 if (ftpFile.isFile()) { 39 System.out.println("********file" + ftpFile.getName() + "The contents are as follows**********"); 40 // ftpClient.completePendingCommand(); // It must not be executed before reading, otherwise it will be locked. 41 42 InputStream inputStream = ftpClient.retrieveFileStream(ftpFile.getName()); 43 try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { 44 while (true) { 45 final String s = reader.readLine(); 46 if (s == null) { 47 break; 48 } 49 System.out.println(s); 50 } 51 } 52 inputStream.close(); 53 ftpClient.completePendingCommand(); // Execute the statement every time you read a file 54 } 55 } 56 } 57 58 public static void main(String[] args) { 59 final TestFTP testFTP = new TestFTP(); 60 FTPClient ftpClient = testFTP.connectServer(); 61 try { 62 testFTP.readFiles(ftpClient); 63 } catch (IOException e) { 64 e.printStackTrace(); 65 } 66 } 67 }