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 馬光([email protected])創建 * 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服務器不太一樣。。。