使用FTPClinet實現瀏覽器能夠訪問FTP服務器各個目錄, 並下載文件的技術代碼

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服務器不太一樣。。。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章