JAVA FTPClient FTP簡單操作

在項(xiàng)目中威沫,經(jīng)常會(huì)用到FTP服務(wù)器,這里做了一個(gè)簡單的聯(lián)系伤哺,基于FTPClient 對FTP文件進(jìn)行操作

package com.lovo.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
 * 簡單操作FTP工具類 ,此工具類支持中文文件名燕侠,不支持中文目錄
 * 如果需要支持中文目錄,需要 new String(path.getBytes("UTF-8"),"ISO-8859-1") 對目錄進(jìn)行轉(zhuǎn)碼
 * @author WZH
 * 
 */
public class FTPUtil {

    private static Logger logger = Logger.getLogger(FTPUtil.class);

    /**
     * 獲取FTPClient對象
     * @param ftpHost 服務(wù)器IP
     * @param ftpPort 服務(wù)器端口號
     * @param ftpUserName 用戶名
     * @param ftpPassword 密碼
     * @return FTPClient
     */
    public FTPClient getFTPClient(String ftpHost, int ftpPort,
            String ftpUserName, String ftpPassword) {

        FTPClient ftp = null;
        try {
            ftp = new FTPClient();
            // 連接FPT服務(wù)器,設(shè)置IP及端口
            ftp.connect(ftpHost, ftpPort);
            // 設(shè)置用戶名和密碼
            ftp.login(ftpUserName, ftpPassword);
            // 設(shè)置連接超時(shí)時(shí)間,5000毫秒
            ftp.setConnectTimeout(50000);
            // 設(shè)置中文編碼集立莉,防止中文亂碼
            ftp.setControlEncoding("UTF-8");
            if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
                logger.info("未連接到FTP绢彤,用戶名或密碼錯(cuò)誤");
                ftp.disconnect();
            } else {
                logger.info("FTP連接成功");
            }

        } catch (SocketException e) {
            e.printStackTrace();
            logger.info("FTP的IP地址可能錯(cuò)誤,請正確配置");
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("FTP的端口錯(cuò)誤,請正確配置");
        }
        return ftp;
    }
    
    /**
     * 關(guān)閉FTP方法
     * @param ftp
     * @return
     */
    public boolean closeFTP(FTPClient ftp){
        
        try {
            ftp.logout();
        } catch (Exception e) {
            logger.error("FTP關(guān)閉失敗");
        }finally{
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error("FTP關(guān)閉失敗");
                }
            }
        }
        
        return false;
        
    }
    
    
    /**
     * 下載FTP下指定文件
     * @param ftp FTPClient對象
     * @param filePath FTP文件路徑
     * @param fileName 文件名
     * @param downPath 下載保存的目錄
     * @return
     */
    public boolean downLoadFTP(FTPClient ftp, String filePath, String fileName,
            String downPath) {
        // 默認(rèn)失敗
        boolean flag = false;

        try {
            // 跳轉(zhuǎn)到文件目錄
            ftp.changeWorkingDirectory(filePath);
            // 獲取目錄下文件集合
            ftp.enterLocalPassiveMode();
            FTPFile[] files = ftp.listFiles();
            for (FTPFile file : files) {
                // 取得指定文件并下載
                if (file.getName().equals(fileName)) {
                    File downFile = new File(downPath + File.separator
                            + file.getName());
                    OutputStream out = new FileOutputStream(downFile);
                    // 綁定輸出流下載文件,需要設(shè)置編碼集蜓耻,不然可能出現(xiàn)文件為空的情況
                    flag = ftp.retrieveFile(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"), out);
                    // 下載成功刪除文件,看項(xiàng)目需求
                    // ftp.deleteFile(new String(fileName.getBytes("UTF-8"),"ISO-8859-1"));
                    out.flush();
                    out.close();
                    if(flag){
                        logger.info("下載成功");
                    }else{
                        logger.error("下載失敗");
                    }
                }
            }

        } catch (Exception e) {
            logger.error("下載失敗");
        } 

        return flag;
    }

    /**
     * FTP文件上傳工具類
     * @param ftp
     * @param filePath
     * @param ftpPath
     * @return
     */
    public boolean uploadFile(FTPClient ftp,String filePath,String ftpPath){
        boolean flag = false;
        InputStream in = null;
        try {
         // 設(shè)置PassiveMode傳輸  
            ftp.enterLocalPassiveMode(); 
            //設(shè)置二進(jìn)制傳輸茫舶,使用BINARY_FILE_TYPE,ASC容易造成文件損壞
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            //判斷FPT目標(biāo)文件夾時(shí)候存在不存在則創(chuàng)建
            if(!ftp.changeWorkingDirectory(ftpPath)){
                ftp.makeDirectory(ftpPath);
            }
            //跳轉(zhuǎn)目標(biāo)目錄
            ftp.changeWorkingDirectory(ftpPath);
            
            //上傳文件
            File file = new File(filePath);
            in = new FileInputStream(file);
            String tempName = ftpPath+File.separator+file.getName();
            flag = ftp.storeFile(new String (tempName.getBytes("UTF-8"),"ISO-8859-1"),in);
            if(flag){
                logger.info("上傳成功");
            }else{
                logger.error("上傳失敗");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("上傳失敗");
        }finally{
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return flag;
    }
    
    /**
     * FPT上文件的復(fù)制
     * @param ftp  FTPClient對象
     * @param olePath 原文件地址
     * @param newPath 新保存地址
     * @param fileName 文件名
     * @return
     */
    public boolean copyFile(FTPClient ftp, String olePath, String newPath,String fileName) {
        boolean flag = false;

        try {
            // 跳轉(zhuǎn)到文件目錄
            ftp.changeWorkingDirectory(olePath);
            //設(shè)置連接模式刹淌,不設(shè)置會(huì)獲取為空
            ftp.enterLocalPassiveMode();
            // 獲取目錄下文件集合
            FTPFile[] files = ftp.listFiles();
            ByteArrayInputStream  in = null;
            ByteArrayOutputStream out = null;
            for (FTPFile file : files) {
                // 取得指定文件并下載 
                if (file.getName().equals(fileName)) {
                    
                    //讀取文件饶氏,使用下載文件的方法把文件寫入內(nèi)存,綁定到out流上
                    out = new ByteArrayOutputStream();
                    ftp.retrieveFile(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"), out);
                    in = new ByteArrayInputStream(out.toByteArray());
                    //創(chuàng)建新目錄
                    ftp.makeDirectory(newPath);
                    //文件復(fù)制,先讀有勾,再寫
                    //二進(jìn)制
                    ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
                    flag = ftp.storeFile(newPath+File.separator+(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1")),in);
                    out.flush();
                    out.close();
                    in.close();
                    if(flag){
                        logger.info("轉(zhuǎn)存成功");
                    }else{
                        logger.error("復(fù)制失敗");
                    }
                    
                    
                }
            }
        } catch (Exception e) {
            logger.error("復(fù)制失敗");
        } 
        return flag;
    }
    
    /**
     * 實(shí)現(xiàn)文件的移動(dòng)疹启,這里做的是一個(gè)文件夾下的所有內(nèi)容移動(dòng)到新的文件,
     * 如果要做指定文件移動(dòng)蔼卡,加個(gè)判斷判斷文件名
     * 如果不需要移動(dòng)喊崖,只是需要文件重命名,可以使用ftp.rename(oleName,newName)
     * @param ftp
     * @param oldPath
     * @param newPath
     * @return
     */
    public boolean moveFile(FTPClient ftp,String oldPath,String newPath){
        boolean flag = false;
        
        try {
            ftp.changeWorkingDirectory(oldPath);
            ftp.enterLocalPassiveMode();
            //獲取文件數(shù)組
            FTPFile[] files = ftp.listFiles();
            //新文件夾不存在則創(chuàng)建
            if(!ftp.changeWorkingDirectory(newPath)){
                ftp.makeDirectory(newPath);
            }
            //回到原有工作目錄
            ftp.changeWorkingDirectory(oldPath);
            for (FTPFile file : files) {

                //轉(zhuǎn)存目錄
                flag = ftp.rename(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"), newPath+File.separator+new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
                if(flag){
                    logger.info(file.getName()+"移動(dòng)成功");
                }else{
                    logger.error(file.getName()+"移動(dòng)失敗");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("移動(dòng)文件失敗");
        }
        return flag;
    }
    
    /**
     * 刪除FTP上指定文件夾下文件及其子文件方法雇逞,添加了對中文目錄的支持
     * @param ftp FTPClient對象
     * @param FtpFolder 需要?jiǎng)h除的文件夾
     * @return
     */
    public boolean deleteByFolder(FTPClient ftp,String FtpFolder){
        boolean flag = false;
        try {
            ftp.changeWorkingDirectory(new String(FtpFolder.getBytes("UTF-8"),"ISO-8859-1"));
            ftp.enterLocalPassiveMode();
            FTPFile[] files = ftp.listFiles();
            for (FTPFile file : files) {
                //判斷為文件則刪除
                if(file.isFile()){
                    ftp.deleteFile(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
                }
                //判斷是文件夾
                if(file.isDirectory()){
                    String childPath = FtpFolder + File.separator+file.getName();
                    //遞歸刪除子文件夾
                    deleteByFolder(ftp,childPath);
                }
            }
            //循環(huán)完成后刪除文件夾
            flag = ftp.removeDirectory(new String(FtpFolder.getBytes("UTF-8"),"ISO-8859-1"));
            if(flag){
                logger.info(FtpFolder+"文件夾刪除成功");
            }else{
                logger.error(FtpFolder+"文件夾刪除成功");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("刪除失敗");
        }
        return flag;
        
    }
    
    /**
     * 遍歷解析文件夾下所有文件
     * @param folderPath 需要解析的的文件夾
     * @param ftp FTPClient對象
     * @return
     */
    public boolean readFileByFolder(FTPClient ftp,String folderPath){
        boolean flage = false;
        try {
            ftp.changeWorkingDirectory(new String(folderPath.getBytes("UTF-8"),"ISO-8859-1"));
            //設(shè)置FTP連接模式
            ftp.enterLocalPassiveMode();
            //獲取指定目錄下文件文件對象集合
            FTPFile files[] = ftp.listFiles();
            InputStream in = null;
            BufferedReader reader = null;
            for (FTPFile file : files) {
                //判斷為txt文件則解析
                if(file.isFile()){
                    String fileName = file.getName();
                    if(fileName.endsWith(".txt")){
                        in = ftp.retrieveFileStream(new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
                        reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
                        String temp;
                        StringBuffer buffer = new StringBuffer();
                        while((temp = reader.readLine())!=null){
                            buffer.append(temp);
                        }
                        if(reader!=null){
                            reader.close();
                        }
                        if(in!=null){
                            in.close();
                        }
                        //ftp.retrieveFileStream使用了流荤懂,需要釋放一下,不然會(huì)返回空指針
                        ftp.completePendingCommand();
                        //這里就把一個(gè)txt文件完整解析成了個(gè)字符串喝峦,就可以調(diào)用實(shí)際需要操作的方法
                        System.out.println(buffer.toString());
                    }
                }
                //判斷為文件夾势誊,遞歸
                if(file.isDirectory()){
                    String path = folderPath+File.separator+file.getName();
                    readFileByFolder(ftp, path);
                }
            }
            
            
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("文件解析失敗");
        }
        
        return flage;
        
    }
    
    public static void main(String[] args) {
        FTPUtil test = new FTPUtil();
        FTPClient ftp = test.getFTPClient("192.168.199.172", 21, "user","password");
        //test.downLoadFTP(ftp, "/file", "你好.jpg", "C:\\下載");
        //test.copyFile(ftp, "/file", "/txt/temp", "你好.txt");
        //test.uploadFile(ftp, "C:\\下載\\你好.jpg", "/");
        //test.moveFile(ftp, "/file", "/txt/temp");
        //test.deleteByFolder(ftp, "/txt");
        test.readFileByFolder(ftp, "/");
        test.closeFTP(ftp);
        System.exit(0);
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谣蠢,隨后出現(xiàn)的幾起案子粟耻,更是在濱河造成了極大的恐慌查近,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挤忙,死亡現(xiàn)場離奇詭異霜威,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)册烈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門戈泼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赏僧,你說我怎么就攤上這事大猛。” “怎么了淀零?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵挽绩,是天一觀的道長。 經(jīng)常有香客問我驾中,道長唉堪,這世上最難降的妖魔是什么肩民? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任唠亚,我火速辦了婚禮,結(jié)果婚禮上持痰,老公的妹妹穿的比我還像新娘灶搜。我一直安慰自己,他們只是感情好共啃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布占调。 她就那樣靜靜地躺著,像睡著了一般移剪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上薪者,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天纵苛,我揣著相機(jī)與錄音,去河邊找鬼言津。 笑死攻人,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的悬槽。 我是一名探鬼主播怀吻,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼初婆!你這毒婦竟也來了蓬坡?” 一聲冷哼從身側(cè)響起猿棉,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屑咳,沒想到半個(gè)月后萨赁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兆龙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年杖爽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片紫皇。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡慰安,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聪铺,到底是詐尸還是另有隱情泻帮,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布计寇,位于F島的核電站锣杂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏番宁。R本人自食惡果不足惜元莫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蝶押。 院中可真熱鬧踱蠢,春花似錦、人聲如沸棋电。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赶盔。三九已至企锌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間于未,已是汗流浹背撕攒。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烘浦,地道東北人抖坪。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像闷叉,于是被迫代替她去往敵國和親擦俐。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評論 25 707
  • 用兩張圖告訴你握侧,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料蚯瞧? 從這篇文章中你...
    hw1212閱讀 12,693評論 2 59
  • 我們決定乘火車從曼谷到清邁嘿期,便提前一天去曼谷華南蓬(Hua Lampur)火車站去購票,買車票的人很少状知,多是歐...
    輝子Wh閱讀 1,082評論 6 4
  • 天使3.0六班 8月31日 1組和5組周檢視會(huì) 1組2號 紀(jì)春玲 我是1組2號我的名字叫紀(jì)春玲很高興和大家一起進(jìn)行...
    紀(jì)春玲閱讀 255評論 0 2