最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java從ftp服務(wù)器上傳與下載文件的實(shí)現(xiàn)

 更新時(shí)間:2023年08月08日 10:42:05   作者:明天再去學(xué)習(xí)  
這篇文章主要給大家介紹了關(guān)于Java從ftp服務(wù)器上傳與下載文件的實(shí)現(xiàn)方法,最近項(xiàng)目中需要實(shí)現(xiàn)將文件先存放到ftp上,需要的時(shí)候再?gòu)膄tp上下載,做的過程中碰到了問題,所以這里總結(jié)下,需要的朋友可以參考下

一、背景

業(yè)務(wù)需要從ftp服務(wù)器上上傳、下載、刪除文件等功能,通過查閱資料及手動(dòng)敲打代碼,實(shí)現(xiàn)了操作ftp的基本功能,有需求的小伙伴可以看看具體的實(shí)現(xiàn)過程。

二、ftp介紹

摘自百度百科:文件傳輸協(xié)議(File Transfer Protocol,F(xiàn)TP)是用于在網(wǎng)絡(luò)上進(jìn)行文件傳輸?shù)囊惶讟?biāo)準(zhǔn)協(xié)議,F(xiàn)TP允許用戶以文件操作的方式(如文件的增、刪、改、查、傳送等)與另一主機(jī)相互通信。

三、具體代碼實(shí)現(xiàn)

1、引入以下依賴

<!--apache下,包含連接ftp服務(wù)器的工具-->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.6</version>
</dependency>

2、編寫一個(gè)FTP工具類

含以下四個(gè)方法:

  • *獲取一個(gè)FtpClinet連接
  • *關(guān)閉FtpClinet連接
  • *下載文件
  • *上傳文件
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.*;
import java.nio.charset.StandardCharsets;
@Slf4j
public class FtpUtil {
    /**
     * 獲取一個(gè)ftp連接
     * @param host ip地址
     * @param port 端口
     * @param username 用戶名
     * @param password 密碼
     * @return 返回ftp連接對(duì)象
     * @throws Exception 連接ftp時(shí)發(fā)生的各種異常
     */
    public static FTPClient getFtpClient(String host, Integer port, String username, String password) throws Exception{
        FTPClient ftpClient = new FTPClient();
        // 連接服務(wù)器
        ftpClient.connect(host, port);
        int reply = ftpClient.getReplyCode();
        if(!FTPReply.isPositiveCompletion(reply)){
            log.error("無法連接至ftp服務(wù)器, host:{}, port:{}", host, port);
            ftpClient.disconnect();
            return null;
        }
        // 登入服務(wù)器
        boolean login = ftpClient.login(username, password);
        if(!login){
            log.error("登錄失敗, 用戶名或密碼錯(cuò)誤");
            ftpClient.logout();
            ftpClient.disconnect();
            return null;
        }
        // 連接并且成功登陸ftp服務(wù)器
        log.info("login success ftp server, host:{}, port:{}, user:{}", host, port, username);
        // 設(shè)置通道字符集, 要與服務(wù)端設(shè)置一致
        ftpClient.setControlEncoding("UTF-8");
        // 設(shè)置文件傳輸編碼類型, 字節(jié)傳輸:BINARY_FILE_TYPE, 文本傳輸:ASCII_FILE_TYPE, 建議使用BINARY_FILE_TYPE進(jìn)行文件傳輸
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        // 動(dòng)模式: enterLocalActiveMode(),被動(dòng)模式: enterLocalPassiveMode(),一般選擇被動(dòng)模式
        ftpClient.enterLocalPassiveMode();
        // 切換目錄
        //ftpClient.changeWorkingDirectory("xxxx");
        return ftpClient;
    }
    /**
     * 斷開ftp連接
     * @param ftpClient ftp連接客戶端
     */
    public static void disConnect(FTPClient ftpClient){
        if(ftpClient == null){
            return;
        }
        try {
            log.info("斷開ftp連接, host:{}, port:{}", ftpClient.getPassiveHost(), ftpClient.getPassivePort());
            ftpClient.logout();
            ftpClient.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("ftp連接斷開異常, 請(qǐng)檢查");
        }
    }
    /**
     * 文件下載
     * @param ftpClient ftp連接客戶端
     * @param path 文件路徑
     * @param fileName 文件名稱
     */
    public static void download(FTPClient ftpClient, String path, String fileName) throws Exception {
        if(ftpClient == null || path == null || fileName == null){
            return;
        }
        // 中文目錄處理存在問題, 轉(zhuǎn)化為ftp能夠識(shí)別中文的字符集
        String remotePath;
        try {
            remotePath = new String(path.getBytes(StandardCharsets.UTF_8), FTP.DEFAULT_CONTROL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            remotePath = path;
        }
        InputStream inputStream = ftpClient.retrieveFileStream(remotePath);
        if (inputStream == null) {
            log.error("{}在ftp服務(wù)器中不存在,請(qǐng)檢查", path);
            return;
        }
        FileOutputStream outputStream = new FileOutputStream("D:\\test\\" + fileName);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        try{
            byte[] buffer = new byte[2048];
            int i;
            while ((i = bufferedInputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, i);
                bufferedOutputStream.flush();
            }
        } catch (Exception e) {
            log.error("文件下載異常", e);
            log.error("{}下載異常,請(qǐng)檢查", path);
        }
        inputStream.close();
        outputStream.close();
        bufferedInputStream.close();
        bufferedOutputStream.close();
        // 關(guān)閉流之后必須執(zhí)行,否則下一個(gè)文件導(dǎo)致流為空
        boolean complete = ftpClient.completePendingCommand();
        if(complete){
            log.info("文件{}下載完成", remotePath);
        }else{
            log.error("文件{}下載失敗", remotePath);
        }
    }
    /**
     * 上傳文件
     * @param ftpClient ftp連接客戶端
     * @param sourcePath 源地址
     */
    public static void upload(FTPClient ftpClient, String sourcePath) throws Exception{
        if(ftpClient == null || sourcePath == null){
            return;
        }
        File file = new File(sourcePath);
        if(!file.exists() || !file.isFile()){
            return;
        }
        // 中文目錄處理存在問題, 轉(zhuǎn)化為ftp能夠識(shí)別中文的字符集
        String remotePath;
        try {
            remotePath = new String(file.getName().getBytes(StandardCharsets.UTF_8), FTP.DEFAULT_CONTROL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            remotePath = file.getName();
        }
        try(
                InputStream inputStream = new FileInputStream(file);
                OutputStream outputStream = ftpClient.storeFileStream(remotePath);
        ){
            byte[] buffer = new byte[2048];
            int length;
            while((length = inputStream.read(buffer)) != -1){
                outputStream.write(buffer, 0, length);
                outputStream.flush();
            }
        }catch (Exception e){
            log.error("文件上傳異常", e);
        }
        // 關(guān)閉流之后必須執(zhí)行,否則下一個(gè)文件導(dǎo)致流為空
        boolean complete = ftpClient.completePendingCommand();
        if(complete){
            log.info("文件{}上傳完成", remotePath);
        }else{
            log.error("文件{}上傳失敗", remotePath);
        }
    }
}

3、測(cè)試連接、上傳文件、下載文件、關(guān)閉連接功能

@Slf4j
@RestController
public class FtpController {
    private static final String FTP_HOST = "your host";
    private static final Integer FTP_PORT = 21;
    private static final String FTP_USERNAME = "your username";
    private static final String FTP_PASSWORD = "your password";
    @GetMapping("/test")
    public void test() throws Exception{
        FTPClient ftpClient = FtpUtil.getFtpClient(FTP_HOST, FTP_PORT, FTP_USERNAME, FTP_PASSWORD);
        // 展示文件夾
        FTPFile[] ftpFiles = ftpClient.listDirectories();
        for(FTPFile file : ftpFiles){
            System.out.println(file.getName());
        }
        // 下載文件
        FtpUtil.download(ftpClient, "test.txt", "test.txt");
        //FtpUtil.download(ftpClient, "test.py", "test.py");
        // 上傳文件
        FtpUtil.upload(ftpClient, "D:\\test\\test.py");
        FtpUtil.disConnect(ftpClient);
    }
}

經(jīng)過測(cè)試,能夠正常連接上ftp服務(wù)器,并且上傳下載文件,最后關(guān)閉連接。

四、遇到的問題

在使用過程中,遇到以下問題,需要記錄一下,以防下次忘記:

就是在創(chuàng)建完一個(gè)FtpClient連接之后,關(guān)閉連接之前,第一次進(jìn)行文件上傳或下載是正常的,當(dāng)?shù)诙芜M(jìn)行文件上傳或下載時(shí),從FtpClient獲取的輸入流或輸出流是空的。需要在每次操作完文件上傳或下載時(shí),添加上以下代碼片段:

// 關(guān)閉流之后必須執(zhí)行,否則下一個(gè)文件導(dǎo)致流為空
boolean complete = ftpClient.completePendingCommand();
if(complete){
    log.info("文件{}下載完成", remotePath);
}else{
    log.error("文件{}下載失敗", remotePath);
}

該方法有以下注釋:

There are a few FTPClient methods that do not complete the entire sequence 
of FTP commands to complete a transaction. These commands require some action 
by the programmer after the reception of a positive intermediate command. 
After the programmer's code completes its actions, it must call this method 
to receive the completion reply from the server and verify the success of the 
entire transaction.

百度翻譯大致意思應(yīng)該是:有一些FTPClient方法不能完成完成事務(wù)的整個(gè)FTP命令序列。這些命令需要程序員在接收到肯定的中間命令后采取一些行動(dòng)。程序員的代碼完成其操作后,必須調(diào)用此方法以從服務(wù)器接收完成回復(fù),并驗(yàn)證整個(gè)事務(wù)的成功。

這里不知道是不是描述的我這種情況, completePedingCommand的意思是完成掛起命令??赡芪覀儺?dāng)前場(chǎng)景就符合。剛興趣的小伙伴可以深入去探討一下。

五、參考連接

到此這篇關(guān)于Java從ftp服務(wù)器上傳與下載文件的文章就介紹到這了,更多相關(guān)Java ftp服務(wù)器上傳下載文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

  • Jmeter中的timeshift()函數(shù)獲取當(dāng)前時(shí)間進(jìn)行加減

    Jmeter中的timeshift()函數(shù)獲取當(dāng)前時(shí)間進(jìn)行加減

    這篇文章主要介紹了Jmeter中的timeshift()函數(shù)獲取當(dāng)前時(shí)間進(jìn)行加減,TimeShift(格式,日期,移位,語言環(huán)境,變量)可對(duì)日期進(jìn)行移位加減操作,本文給大家詳細(xì)講解,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • 基于Java實(shí)現(xiàn)中文分詞系統(tǒng)的示例代碼

    基于Java實(shí)現(xiàn)中文分詞系統(tǒng)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)一個(gè)簡(jiǎn)易的中文分詞系統(tǒng),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-07-07
  • java代碼實(shí)現(xiàn)編譯源文件

    java代碼實(shí)現(xiàn)編譯源文件

    這篇文章主要為大家詳細(xì)介紹了Java通過?JavaCompiler?實(shí)現(xiàn)編譯源文件的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2025-01-01
  • 實(shí)例詳解Java調(diào)用第三方接口方法

    實(shí)例詳解Java調(diào)用第三方接口方法

    很多項(xiàng)目都會(huì)封裝規(guī)定好本身項(xiàng)目的接口規(guī)范,所以大多數(shù)需要去調(diào)用對(duì)方提供的接口或第三方接口(短信、天氣等),下面這篇文章主要給大家介紹了關(guān)于Java調(diào)用第三方接口方法的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Java 如何將 byte[] 轉(zhuǎn)換為 File 對(duì)象

    Java 如何將 byte[] 轉(zhuǎn)換為 File 對(duì)象

    本文介紹了如何將字節(jié)數(shù)組(byte[])轉(zhuǎn)換為文件對(duì)象(File)的方法,提供了具體代碼示例,代碼簡(jiǎn)單易懂,感興趣的朋友跟隨小編一起看看吧
    2025-03-03
  • 解決Servlet4.0版本使用注解設(shè)置url但無法訪問的問題

    解決Servlet4.0版本使用注解設(shè)置url但無法訪問的問題

    在學(xué)習(xí)servlet過程中,使用web.xml文件配置servlet可以正常訪問,但使用WebServlet注解時(shí)出現(xiàn)404錯(cuò)誤,解決方法是在web.xml文件中將metadata-complete屬性改為false,啟動(dòng)標(biāo)注支持,然而該方法對(duì)我無效,最后通過重建項(xiàng)目和手動(dòng)將新建的項(xiàng)目添加到tomcat服務(wù)器解決問題
    2024-10-10
  • Springboot集成Camunda使用Mysql介紹

    Springboot集成Camunda使用Mysql介紹

    大家好,本篇文章主要講的是Springboot集成Camunda使用Mysql介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component的深度解析

    Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component的深度解析

    在現(xiàn)代微服務(wù)架構(gòu)中,動(dòng)態(tài)配置管理是一個(gè)關(guān)鍵需求,Spring Cloud 提供了 @RefreshScope 注解,允許應(yīng)用在運(yùn)行時(shí)動(dòng)態(tài)更新配置,而無需重啟服務(wù),本文深入探析Spring Cloud動(dòng)態(tài)配置刷新@RefreshScope與@Component,感興趣的朋友一起看看吧
    2025-04-04
  • Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決

    Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決

    本文主要介紹了Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 最新評(píng)論

    东莞市| 平谷区| 兴安县| 武鸣县| 独山县| 都兰县| 嘉善县| 涪陵区| 北宁市| 普宁市| 甘孜县| 大渡口区| 和龙市| 化隆| 东乌珠穆沁旗| 道孚县| 尖扎县| 丹寨县| 名山县| 金昌市| 泽普县| 新平| 浪卡子县| 图片| 阜南县| 娄烦县| 阿鲁科尔沁旗| 化德县| 兴海县| 华阴市| 威海市| 滁州市| 东光县| 比如县| 黔江区| 乌兰察布市| 黄石市| 金门县| 镇雄县| 名山县| 进贤县|