java连接ftp

文章探讨了在使用FTPClient进行文件操作时,如何设置连接超时以防止程序因连接问题假死。重点介绍了被动模式、主动模式的区别,以及如何在操作文件时重置超时时间,以确保高效且稳定的文件传输。
摘要由CSDN通过智能技术生成

连接

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连接那个方法是开启一个线程的,然后你下载文件也是用同一个线程,然后就会阻塞
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值