package com.sugon.cloudview.cmz.compute; import com.sugon.cloudview.common.base.exception.CloudviewException; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; public class FtpTest { public static void main(String[] args) throws Exception { //ftp://10.0.38.45/mag/ downFile("10.0.38.45", 21, "mag", "Sugon@123", "/mag", "cirros-0.4.0-x86_64-disk.iso"); } /** * by 马光(cuihongbao@d-heaven.com)创建 * Description: 从FTP服务器拿到任意一个文件流 * other_description: 通过此方法可以实现浏览器进入ftp服务器的各个目录, 进一步拿到各个目录下的文件 * @param url FTP服务器hostname或者ip * @param port FTP服务器端口,默认为21 * @param username FTP登录账号, 如果无账号密码, 此处设置为 anonymous * @param password FTP登录密码 * @param pathname FTP服务器上的相对路径 * @param fileName 要下载的文件名 * @return */ public static void downFile(String url, int port,String username, String password, String pathname,String fileName) throws Exception { FTPClient ftpClient = new FTPClient(); ftpClient.setControlEncoding("utf-8"); //设置连接超时: 不设置,账号密码或者url不正确,会阻塞很长时间 ftpClient.setConnectTimeout(3000); ftpClient.connect(url, port); //连接ftp服务器 ftpClient.login(username, password);//登录ftp服务器 int replyCode = ftpClient.getReplyCode();//是否成功登录服务器 if (!FTPReply.isPositiveCompletion(replyCode)) { ftpClient.disconnect(); throw new Exception("FTP连接未成功,请检查路径、账号和密码是否正确"); } /** * FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。 * 在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode(); * 这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。 * 为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上或者其他服务器上面, * 由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决 */ ftpClient.enterLocalPassiveMode(); /** * 获取ftp工作目录的根路径 * 因为后边需要调用 changeWorkingDirectory方法切换ftpClient的工作路径 * 我测试到的windos的FTP服务器的基础路径就是"/" * 但是linux的FTP的FTPFTP服务器的基础路径是FTP存储目录,比如/home/mag, 如果我们使用"/",则是linux的根路径 * 而通过FTPClient不能拿到FTPClient的工作路径 * 所以通过pwd命令拿到文件的工作路径 */ String[] rt = ftpClient.doCommandAsStrings("pwd", ""); Pattern p= Pattern.compile("\"(.*?)\""); Matcher m=p.matcher(rt[0]); String basePath = "/"; if(m.find()){ basePath = m.group(0).replace("\"", ""); } /** * 切换ftpclient的工作路径: * 可以进入要下载的文件的目录 */ ftpClient.changeWorkingDirectory(basePath + pathname); boolean flag = false; //验证登录 FTPFile[] ftpFiles = ftpClient.listFiles(); if (ftpFiles.length == 0) { throw new CloudviewException("文件未找到"); } /** * 这个配置需要特别注意: * 不设置的话,我们下载的文件和原文件大小不一样(小文件可能一样, 文件越大越明显) * 具体原因可以百度 */ ftpClient.setFileType(FTP.BINARY_FILE_TYPE); for (FTPFile file : ftpFiles) { if (fileName.equalsIgnoreCase(file.getName())) { InputStream inputStream = ftpClient.retrieveFileStream(file.getName()); //此处为FTP文件流 } } ftpClient.disconnect(); ftpClient.logout(); } }
推荐博文:
linux搭建ftp服务器
https://baijiahao.baidu.com/s?id=1619217831603089684&wfr=spider&for=pc
https://blog.csdn.net/LMXQH/article/details/80274038
windows搭建ftp服务器
https://www.cnblogs.com/xidianlxf/p/11032974.html
注:linux和windows的FTP服务器不太一样。。。