分享一个Java ftp文件下载的方法
最近遇到一个ftp下载超时的问题,解决方法如下:
1 /** 2 * 从 FTP 服务器下载文件并写入输出流 3 * 4 * @param ftpUrl FTP 文件的 URL 5 * @param os 输出流 6 */ 7 public static void writeBytesFromFTP(String ftpUrl, OutputStream os) throws IOException { 8 // 解析 FTP URL 9 URL url = new URL(ftpUrl); 10 String host = url.getHost(); 11 String path = url.getPath(); 12 int lastSlashIndex = path.lastIndexOf('/'); 13 String filename = path.substring(lastSlashIndex + 1); 14 // 默认端口为 21 15 int port = url.getPort() > 0 ? url.getPort() : 21; 16 FTPClient ftp = new FTPClient(); 17 ftp.setControlEncoding("UTF-8"); 18 // 设置连接超时时间为5秒 19 ftp.setConnectTimeout(5000); 20 // 设置数据传输的超时时间也为30秒 21 ftp.setDataTimeout(Duration.ofSeconds(30)); 22 try { 23 // 1.连接服务器 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 24 ftp.connect(host, port); 25 // 2.登录服务器 26 boolean loginSuccess = ftp.login(YmlPropertyUtils.getErpFtpName(), YmlPropertyUtils.getErpFtpPwd()); 27 if (!loginSuccess) { 28 throw new RuntimeException("FTP文件服务器登录失败,请检查用户名和密码!"); 29 } 30 // 3.判断连接是否成功 31 int reply = ftp.getReplyCode(); 32 // 确定回复代码是否为肯定的完成响应。所有以 2 开头的代码都是肯定的完成响应。FTP 服务器将在命令最终成功完成时发送肯定的完成响应。 33 if (!FTPReply.isPositiveCompletion(reply)) { 34 throw new RuntimeException("FTP连接失败!"); 35 } 36 37 //4.指定要下载的目录,转移到FTP服务器目录 38 String directory = new File(path).getParent(); 39 directory = directory == null ? "" : directory; 40 // 设置控制命令的超时时间 41 ftp.setSoTimeout(5000); 42 boolean b = ftp.changeWorkingDirectory(directory); 43 if (!b) { 44 throw new RuntimeException("FTP文件服务器切换目录失败,请检查目录是否正确!"); 45 } 46 // 5.遍历下载的目录 47 FTPFile[] fs; 48 try { 49 // 进入本地被动模式,这个东西放在listFiles前面,否则会超时 50 ftp.enterLocalPassiveMode(); 51 // 此信息是通过 LIST 命令获取的, 故要进入本地被动模式(具体原因查看源码或者了解ftp的下载机制) 52 fs = ftp.listFiles(); 53 } catch (IOException e) { 54 throw new RuntimeException("列出FTP目录时发生错误", e); 55 } 56 if (fs != null) { 57 for (FTPFile ff : fs) { 58 //解决中文乱码问题,两次解码 59 String fn = new String(ff.getName().getBytes("iso-8859-1"), "utf8"); 60 if (fn.equals(filename)) { 61 //6.写操作,将其写入到输出流 62 ftp.retrieveFile(ff.getName(), os); 63 break; 64 } 65 } 66 } else { 67 throw new RuntimeException("FTP文件服务器没有找到文件,请检查文件名是否正确!"); 68 } 69 } catch (Exception e) { 70 throw new RuntimeException("从服务器下载文件过程中发生错误", e); 71 } finally { 72 if (os != null) { 73 os.flush(); 74 os.close(); 75 } 76 // 关闭连接 77 if (ftp.isConnected()) { 78 try { 79 ftp.logout(); 80 ftp.disconnect(); 81 } catch (IOException ioe) { 82 log.error("关闭FTP连接时发生错误", ioe); 83 } 84 } 85 } 86 }

浙公网安备 33010602011771号