java基於FTPClient寫個Ftp工具類


1、添加依賴的jar包

  以gradle添加依賴為例

compile "org.apache.commons:commons-lang3:3.6"
compile "commons-net:commons-net:3.6"
View Code

2、封裝下FTPClient

package com.moy.demo.common.utils;

import org.apache.commons.lang3.StringUtils;
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.*;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>Description: [ftp工具類]</p>
 * Created on 2018/6/4
 *
 * @author 葉向陽
 * @version 1.0
 */
public class FtpCli {
    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final int DEFAULT_TIMEOUT = 60 * 1000;
    private static final String DAILY_FILE_PATH = "dailyFilePath";
    private final String host;
    private final int port;
    private final String username;
    private final String password;
    private FTPClient ftpClient;
    private volatile String ftpBasePath;

    private FtpCli(String host, String username, String password) {
        this(host, 21, username, password, DEFAULT_CHARSET);
        setTimeout(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT);
    }

    private FtpCli(String host, int port, String username, String password, String charset) {
        ftpClient = new FTPClient();
        ftpClient.setControlEncoding(charset);
        this.host = StringUtils.isEmpty(host) ? "localhost" : host;
        this.port = (port <= 0) ? 21 : port;
        this.username = StringUtils.isEmpty(username) ? "anonymous" : username;
        this.password = password;
    }

    /**
     * <p>Description:[創建默認的ftp客戶端]</p>
     * Created on 2018/6/5
     *
     * @param host     主機名或者ip地址
     * @param username ftp用戶名
     * @param password ftp密碼
     * @return com.moy.demo.common.utils.FtpCli
     * @author 葉向陽
     */
    public static FtpCli createFtpCli(String host, String username, String password) {
        return new FtpCli(host, username, password);
    }

    /**
     * <p>Description:[創建自定義屬性的ftp客戶端]</p>
     * Created on 2018/6/5
     *
     * @param host     主機名或者ip地址
     * @param port     ftp端口
     * @param username ftp用戶名
     * @param password ftp密碼
     * @param charset  字符集
     * @return com.moy.demo.common.utils.FtpCli
     * @author 葉向陽
     */
    public static FtpCli createFtpCli(String host, int port, String username, String password, String charset) {
        return new FtpCli(host, port, username, password, charset);
    }

    /**
     * <p>Description:[設置超時時間]</p>
     * Created on 2018/6/5
     *
     * @param defaultTimeout 超時時間
     * @param connectTimeout 超時時間
     * @param dataTimeout    超時時間
     * @author 葉向陽
     */
    public void setTimeout(int defaultTimeout, int connectTimeout, int dataTimeout) {
        ftpClient.setDefaultTimeout(defaultTimeout);
        ftpClient.setConnectTimeout(connectTimeout);
        ftpClient.setDataTimeout(dataTimeout);
    }

    /**
     * <p>Description:[連接到ftp]</p>
     * Created on 2018/6/5
     *
     * @author 葉向陽
     */
    public void connect() throws IOException {
        try {
            ftpClient.connect(host, port);
        } catch (UnknownHostException e) {
            throw new IOException("Can't find FTP server :" + host);
        }

        int reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect();
            throw new IOException("Can't connect to server :" + host);
        }

        if (!ftpClient.login(username, password)) {
            disconnect();
            throw new IOException("Can't login to server :" + host);
        }

        // set data transfer mode.
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

        // Use passive mode to pass firewalls.
        ftpClient.enterLocalPassiveMode();

        initFtpBasePath();
    }

    /**
     * <p>Description:[連接ftp時保存剛登陸ftp時的路徑]</p>
     * Created on 2018/6/6
     *
     * @author 葉向陽
     */
    private void initFtpBasePath() throws IOException {
        if (StringUtils.isEmpty(ftpBasePath)) {
            synchronized (this) {
                if (StringUtils.isEmpty(ftpBasePath)) {
                    ftpBasePath = ftpClient.printWorkingDirectory();
                }
            }
        }
    }

    /**
     * <p>Description:[ftp是否處於連接狀態,是連接狀態返回<tt>true</tt>]</p>
     * Created on 2018/6/5
     *
     * @return boolean  是連接狀態返回<tt>true</tt>
     * @author 葉向陽
     */
    public boolean isConnected() {
        return ftpClient.isConnected();
    }

    /**
     * <p>Description:[上傳文件到對應日期文件下,
     * 如當前時間是2018-06-06,則上傳到[ftpBasePath]/[DAILY_FILE_PATH]/2018/06/06/下]</p>
     * Created on 2018/6/6
     *
     * @param fileName    文件名
     * @param inputStream 文件輸入流
     * @return java.lang.String
     * @author 葉向陽
     */
    public String uploadFileToDailyDir(String fileName, InputStream inputStream) throws IOException {
        changeWorkingDirectory(ftpBasePath);
        SimpleDateFormat dateFormat = new SimpleDateFormat("/yyyy/MM/dd");
        String formatDatePath = dateFormat.format(new Date());
        String uploadDir = DAILY_FILE_PATH + formatDatePath;
        makeDirs(uploadDir);
        storeFile(fileName, inputStream);
        return formatDatePath + "/" + fileName;
    }

    /**
     * <p>Description:[根據uploadFileToDailyDir返回的路徑,從ftp下載文件到指定輸出流中]</p>
     * Created on 2018/6/6
     *
     * @param dailyDirFilePath 方法uploadFileToDailyDir返回的路徑
     * @param outputStream     輸出流
     * @author 葉向陽
     */
    public void downloadFileFromDailyDir(String dailyDirFilePath, OutputStream outputStream) throws IOException {
        changeWorkingDirectory(ftpBasePath);
        String ftpRealFilePath = DAILY_FILE_PATH + dailyDirFilePath;
        ftpClient.retrieveFile(ftpRealFilePath, outputStream);
    }

    /**
     * <p>Description:[獲取ftp上指定文件名到輸出流中]</p>
     * Created on 2018/6/5
     *
     * @param ftpFileName 文件在ftp上的路徑  如絕對路徑 /home/ftpuser/123.txt 或者相對路徑 123.txt
     * @param out         輸出流
     * @author 葉向陽
     */
    public void retrieveFile(String ftpFileName, OutputStream out) throws IOException {
        try {
            FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
            if (fileInfoArray == null || fileInfoArray.length == 0) {
                throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
            }

            FTPFile fileInfo = fileInfoArray[0];
            if (fileInfo.getSize() > Integer.MAX_VALUE) {
                throw new IOException("File '" + ftpFileName + "' is too large.");
            }

            if (!ftpClient.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path.");
            }
            out.flush();
        } finally {
            closeStream(out);
        }
    }


    /**
     * <p>Description:[將輸入流存儲到指定的ftp路徑下]</p>
     * Created on 2018/6/6
     *
     * @param ftpFileName 文件在ftp上的路徑 如絕對路徑 /home/ftpuser/123.txt 或者相對路徑 123.txt
     * @param in          輸入流
     * @author 葉向陽
     */
    public void storeFile(String ftpFileName, InputStream in) throws IOException {
        try {
            if (!ftpClient.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }
        } finally {
            closeStream(in);
        }
    }

    /**
     * <p>Description:[根據文件ftp路徑名稱刪除文件]</p>
     * Created on 2018/6/6
     *
     * @param ftpFileName 文件ftp路徑名稱
     * @author 葉向陽
     */
    public void deleteFile(String ftpFileName) throws IOException {
        if (!ftpClient.deleteFile(ftpFileName)) {
            throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server.");
        }
    }

    /**
     * <p>Description:[上傳文件到ftp]</p>
     * Created on 2018/6/6
     *
     * @param ftpFileName 上傳到ftp文件路徑名稱
     * @param localFile   本地文件路徑名稱
     * @author 葉向陽
     */
    public void upload(String ftpFileName, File localFile) throws IOException {
        if (!localFile.exists()) {
            throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");
        }

        InputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(localFile));
            if (!ftpClient.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }
        } finally {
            closeStream(in);
        }
    }

    /**
     * <p>Description:[上傳文件夾到ftp上]</p>
     * Created on 2018/6/6
     *
     * @param remotePath ftp上文件夾路徑名稱
     * @param localPath  本地上傳的文件夾路徑名稱
     * @author 葉向陽
     */
    public void uploadDir(String remotePath, String localPath) throws IOException {
        localPath = localPath.replace("\\\\", "/");
        File file = new File(localPath);
        if (file.exists()) {
            if (!ftpClient.changeWorkingDirectory(remotePath)) {
                ftpClient.makeDirectory(remotePath);
                ftpClient.changeWorkingDirectory(remotePath);
            }
            File[] files = file.listFiles();
            if (null != files) {
                for (File f : files) {
                    if (f.isDirectory() && !f.getName().equals(".") && !f.getName().equals("..")) {
                        uploadDir(remotePath + "/" + f.getName(), f.getPath());
                    } else if (f.isFile()) {
                        upload(remotePath + "/" + f.getName(), f);
                    }
                }
            }
        }
    }

    /**
     * <p>Description:[下載ftp文件到本地上]</p>
     * Created on 2018/6/6
     *
     * @param ftpFileName ftp文件路徑名稱
     * @param localFile   本地文件路徑名稱
     * @author 葉向陽
     */
    public void download(String ftpFileName, File localFile) throws IOException {
        OutputStream out = null;
        try {
            FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
            if (fileInfoArray == null || fileInfoArray.length == 0) {
                throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server.");
            }

            FTPFile fileInfo = fileInfoArray[0];
            if (fileInfo.getSize() > Integer.MAX_VALUE) {
                throw new IOException("File " + ftpFileName + " is too large.");
            }

            out = new BufferedOutputStream(new FileOutputStream(localFile));
            if (!ftpClient.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path.");
            }
            out.flush();
        } finally {
            closeStream(out);
        }
    }


    /**
     * <p>Description:[改變工作目錄]</p>
     * Created on 2018/6/6
     *
     * @param dir ftp服務器上目錄
     * @return boolean 改變成功返回true
     * @author 葉向陽
     */
    public boolean changeWorkingDirectory(String dir) {
        if (!ftpClient.isConnected()) {
            return false;
        }
        try {
            return ftpClient.changeWorkingDirectory(dir);
        } catch (IOException e) {
        }

        return false;
    }

    /**
     * <p>Description:[下載ftp服務器下文件夾到本地]</p>
     * Created on 2018/6/6
     *
     * @param remotePath ftp上文件夾路徑名稱
     * @param localPath  本地上傳的文件夾路徑名稱
     * @return void
     * @author 葉向陽
     */
    public void downloadDir(String remotePath, String localPath) throws IOException {
        localPath = localPath.replace("\\\\", "/");
        File file = new File(localPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        FTPFile[] ftpFiles = ftpClient.listFiles(remotePath);
        for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
            FTPFile ftpFile = ftpFiles[i];
            if (ftpFile.isDirectory() && !ftpFile.getName().equals(".") && !ftpFile.getName().equals("..")) {
                downloadDir(remotePath + "/" + ftpFile.getName(), localPath + "/" + ftpFile.getName());
            } else {
                download(remotePath + "/" + ftpFile.getName(), new File(localPath + "/" + ftpFile.getName()));
            }
        }
    }


    /**
     * <p>Description:[列出ftp上文件目錄下的文件]</p>
     * Created on 2018/6/6
     *
     * @param filePath ftp上文件目錄
     * @return java.util.List<java.lang.String>
     * @author 葉向陽
     */
    public List<String> listFileNames(String filePath) throws IOException {
        FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
        List<String> fileList = new ArrayList<>();
        if (ftpFiles != null) {
            for (int i = 0; i < ftpFiles.length; i++) {
                FTPFile ftpFile = ftpFiles[i];
                if (ftpFile.isFile()) {
                    fileList.add(ftpFile.getName());
                }
            }
        }

        return fileList;
    }

    /**
     * <p>Description:[發送ftp命令到ftp服務器中]</p>
     * Created on 2018/6/6
     *
     * @param args ftp命令
     * @author 葉向陽
     */
    public void sendSiteCommand(String args) throws IOException {
        if (!ftpClient.isConnected()) {
            ftpClient.sendSiteCommand(args);
        }
    }

    /**
     * <p>Description:[獲取當前所處的工作目錄]</p>
     * Created on 2018/6/6
     *
     * @return java.lang.String 當前所處的工作目錄
     * @author 葉向陽
     */
    public String printWorkingDirectory() {
        if (!ftpClient.isConnected()) {
            return "";
        }

        try {
            return ftpClient.printWorkingDirectory();
        } catch (IOException e) {
            // do nothing
        }

        return "";
    }

    /**
     * <p>Description:[切換到當前工作目錄的父目錄下]</p>
     * Created on 2018/6/6
     *
     * @return boolean 切換成功返回true
     * @author 葉向陽
     */
    public boolean changeToParentDirectory() {

        if (!ftpClient.isConnected()) {
            return false;
        }

        try {
            return ftpClient.changeToParentDirectory();
        } catch (IOException e) {
            // do nothing
        }

        return false;
    }

    /**
     * <p>Description:[返回當前工作目錄的上一級目錄]</p>
     * Created on 2018/6/6
     *
     * @return java.lang.String 當前工作目錄的父目錄
     * @author 葉向陽
     */
    public String printParentDirectory() {
        if (!ftpClient.isConnected()) {
            return "";
        }

        String w = printWorkingDirectory();
        changeToParentDirectory();
        String p = printWorkingDirectory();
        changeWorkingDirectory(w);

        return p;
    }

    /**
     * <p>Description:[創建目錄]</p>
     * Created on 2018/6/6
     *
     * @param pathname 路徑名
     * @return boolean 創建成功返回true
     * @author 葉向陽
     */
    public boolean makeDirectory(String pathname) throws IOException {
        return ftpClient.makeDirectory(pathname);
    }

    /**
     * <p>Description:[創建多個目錄]</p>
     * Created on 2018/6/6
     *
     * @param pathname 路徑名
     * @author 葉向陽
     */
    public void makeDirs(String pathname) throws IOException {
        pathname = pathname.replace("\\\\", "/");
        String[] pathnameArray = pathname.split("/");
        for (String each : pathnameArray) {
            if (StringUtils.isNotEmpty(each)) {
                ftpClient.makeDirectory(each);
                ftpClient.changeWorkingDirectory(each);
            }
        }
    }

    /**
     * <p>Description:[關閉流]</p>
     * Created on 2018/6/6
     *
     * @param stream 流
     * @author 葉向陽
     */
    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException ex) {
                // do nothing
            }
        }
    }

    /**
     * <p>Description:[關閉ftp連接]</p>
     * Created on 2018/6/6
     *
     * @author 葉向陽
     */
    public void disconnect() {
        if (null != ftpClient && ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException ex) {
                // do nothing
            }
        }
    }
}
View Code

3、簡單測試下

package com.moy.demo.common.utils;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import static org.junit.Assert.*;

/**
 * <p>Description: [類功能描述]</p>
 * Created on 2018/6/6
 *
 * @author 葉向陽
 * @version 1.0
 */
public class FtpCliTest {
    FtpCli ftpCli;
    File file;

    @Before
    public void before() throws IOException {
        ftpCli = FtpCli.createFtpCli("192.168.169.xxx", "ftpuser", "ftpuser");
        ftpCli.connect();

        String fileName = "testFtp.tmp";
        file = new File(fileName);
        file.createNewFile();
    }

    @After
    public void after() {
        ftpCli.disconnect();
    }

    @Test
    public void uploadFileToDailyDir() throws IOException {
        String path = ftpCli.uploadFileToDailyDir(file.getName(), new FileInputStream(file));
        ftpCli.downloadFileFromDailyDir(path , new FileOutputStream(new File("testFtp.txt")));
    }
}
View Code

 

yexiangyang

moyyexy@gmail.com


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM