- 扫描ftp目录判断文件是否存在
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
public class Test {
public static void main(String[] args) {
try {
FTPClient ftpClient = new FTPClient();
// initialize ftp connection
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
ftpClient.configure(conf);
ftpClient.setDefaultPort(21);//端口号
ftpClient.connect("127.0.0.1");//IP
ftpClient.setDataTimeout(60000); // 设置传输超时时间为60秒
ftpClient.setConnectTimeout(60000);
if (!ftpClient.login("user", "pass")) {//登录的用户名密码
throw new IOException("FTP登陆失败,请检测登陆用户名和密码是否正确!");
}
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory("/test/");//转入到指定的目录文件下
String remotefile = "test.txt";
InputStream is = null;
is = ftpClient.retrieveFileStream(remotefile); //传入文件名即可
//调用这个接口后,一定要手动close掉返回的InputStream,然后再调用completePendingCommand方法,若不是按照这个顺序,则会导致后面对FTPClient的操作都失败
if (is != null) {
System.out.println("存在该文件。。。");
is.close();
ftpClient.completePendingCommand(); // 必须执行,否则在循环检查多个文件时会出错
}
// continue
if (ftpClient != null) {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//当只知道部分文件名时判断文件是否存在
FTPFile[] files = ftpClient.listFiles();
System.out.println("files.length"+files.length);
if(files.length == 0){
return;
}
for(FTPFile file : files){
System.out.println("fileName:"+file.getName());
String fileName = file.getName();
if(fileName.isEmpty()){
return;
}
if(fileName.contains(remotefile)){
System.out.println("存在该文件。。。");
break;
}
}
//创建目录
ftpClient.makeDirectory(path);
- InputStream is = ftpClient.retrieveFileStream(filename);
当调用此方法得到输入流,流操作过后必须先关闭,再调用completePendingCommand方法,不然后面对ftpClient的操作都会失败
retrieveFileStream 传入文件名即可,你使用FTPClient时,要先用changeWorkingDirectory(String pathname)转入到指定的目录文件下的。然后,你在这个目录下获取文件就好
- ftpClient.retrieveFileStream导致FTPClient的后面操作失败
原因:
- 官方说法是:完成文件传输必须调用completependingcommand和检查它的返回值来验证成功。如果没有这样做,后续命令可能会意外地出错
- 简单来说:completePendingCommand()会一直在等FTP Server返回226 Transfer complete,但是FTP Server只有在接受到InputStream执行close方法时,才会返回。所以先要执行close方法
在使用public InputStream retrieveFileStream(String remote) 需要特别注意:
调用这个接口后,一定要手动close掉返回的InputStream,然后再调用completePendingCommand方法,若不是按照这个顺序,则会导致后面对FTPClient的操作都失败
解决方案:
1. 关闭流,调用completePendingCommand()方法
InputStream in = ftpClient.retrieveFileStream(fileName);
in.close();
ftpClient.completePendingCommand();
2. 生成临时文件转换层流返回
//生成临时文件
File tempFile = new File(localPath, localFileName);
OutputStream outputStream = new FileOutputStream(tempFile);
//检索指定从服务器上的文件并将其写入给定的输出流
ftpClient.retrieveFile(fileName, outputStream);
outputStream.close();
InputStream inputStream = new FileInputStream(tempFile);
3 . 调用ftpClient.retrieveFile(fileName, outputStream)
File file = new File(filePath, fileName);
OutputStream outputStream = new FileOutputStream(file);
//检索指定从服务器上的文件并将其写入给定的输出流
ftpClient.retrieveFile(fileName, outputStream);