连接
public static FTPClient connect(){
FTPClient ftpClient = new FTPClient();
// 支持中文
ftpClient.setControlEncoding("utf-8");
try {
ftpClient.connect(HOST);
// 被动模式
//告诉ftp server开通一个端口传输数据,在登录前后设置都可以
//ftp server可能每次都开启不同的端口来传输数据,在linux上面由于安全
//限制,可能某些端口没有开启,出现阻塞,调用这个方法,开启端口
// 因为每次主动去拿,会被系统所拦截掉,然后需要等待它给。
ftpClient.enterLocalPassiveMode();
// 主动模式(默认)
ftpClient.enterLocalActiveMode();
ftpClient.login(USERNAME,PASSWARD);
// 设置文件类型为二进制
// 如果从FTP下载或上传的文件是压缩文件的时候,
// 不进行该设置可能会导致获取的压缩文件解压失败
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 是否成功登录服务器
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
ftpClient.disconnect();
ftpClient = null;
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (ftpClient.isConnected()) {
ftpClient.isConnected();
}
}
return ftpClient;
}
操作文件
//连接ftp
FTPClient connect = FtpUtils.connect();
if (connect == null) {
return;
}
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
Date now = new Date();
try {
//以二进制的形式下载文件,否则下载压缩包时解压报错(linux)
connect.setFileType(FTP.BINARY_FILE_TYPE);
//修改工作目录,默认为gen
connect.changeWorkingDirectory('aa')
FTPFile[] ftpFiles = connect.listFiles();
for (FTPFile ftpFile : ftpFiles) {
User user= new User ();
user.seMc(ftpFile.getName());
Integer count = oracleService.selDataCount(user);
if (1 > count) {
Set<String> set = new HashSet<>();
//重置超时时间,如果长时间操作时可能会断开连接
connect.sendCommand("pwd");
InputStream inputStream = connect.retrieveFileStream(ftpFile.getName());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = bufferedReader.readLine();
while (line != null){
set.add(line);
line = bufferedReader.readLine();
}
bufferedReader.close();
inputStream.close();
oracleService.addTlData(set,ftpFile.getName());
/**
* 官方说法文件传输完成之后必须调用这个方法来验证成功,否则后面会出错。
* 该方法会一直等待ftp服务器返回226 Transfer complete。
* 但是这个方法只有在接受到inputStream执行close方法之后才会返回
* 所以必须要执行 inputStream.close()
*/
connect.completePendingCommand();
}
String fileTime = ftpFile.getName().substring(10, 24);
Date fileDate = format.parse(fileTime);
if((now.getTime() - fileDate.getTime()) > 7*24*60*60*1000){
System.out.println("delete--" + ftpFile.getName());
connect.dele(ftpFile.getName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
超时设置
单位:ms。
- setConnectTimeout() 用于设置终端 Socket 与 FTP 服务器建立连接这个过程的超时时间。
- setDefaultTimeout() 用于设置终端的传输控制命令的 Socket 的 SoTimeout,即针对传输控制命令的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
- setSoTimeout() 作用跟上个方法一样,区别仅在于该方法设置的超时会覆盖掉上个方法设置的值。
- setDataTimeout() 用于设置终端的传输数据的 Socket 的 Sotimeout,即针对传输文件数据的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
- setControlKeepAliveTimeout() 用于设置当处于传输数据过程中,按指定的时间阈值定期让传输控制命令的 Socket 发送一个无操作命令 NOOP 给服务器,让它 keep alive。
- setControlKeepAliveReplyTimeout():只有调用上个方法后,该方法才能生效,用于设置在传输数据这个过程中,暂时替换掉传输控制命令的 Socket 的 SoTimeout,传输过程结束恢复这个 Socket 原本的 SoTimeout。
设置ftpclient超时属性一定要在connect(连接)前设置好,否则不会生效
造成程序假死
- 原因ftpClient.retrieveFile(ff.getName(), os);这个方法
- 主动模式系统限制端口
- 还有就是因为ftp连接那个方法是开启一个线程的,然后你下载文件也是用同一个线程,然后就会阻塞