Java从ftp服务器上传与下载文件

这篇具有很好参考价值的文章主要介绍了Java从ftp服务器上传与下载文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

业务需要从ftp服务器上上传、下载、删除文件等功能,通过查阅资料及手动敲打代码,实现了操作ftp的基本功能,有需求的小伙伴可以看看具体的实现过程。

二、ftp介绍

摘自百度百科:文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。

三、具体代码实现

1、引入以下依赖

<!--apache下,包含连接ftp服务器的工具-->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.6</version>
</dependency>

2、编写一个FTP工具类

含以下四个方法:

*获取一个FtpClinet连接

*关闭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 {

    /**
     * 获取一个ftp连接
     * @param host ip地址
     * @param port 端口
     * @param username 用户名
     * @param password 密码
     * @return 返回ftp连接对象
     * @throws Exception 连接ftp时发生的各种异常
     */
    public static FTPClient getFtpClient(String host, Integer port, String username, String password) throws Exception{
        FTPClient ftpClient = new FTPClient();

        // 连接服务器
        ftpClient.connect(host, port);

        int reply = ftpClient.getReplyCode();
        if(!FTPReply.isPositiveCompletion(reply)){
            log.error("无法连接至ftp服务器, host:{}, port:{}", host, port);
            ftpClient.disconnect();
            return null;
        }

        // 登入服务器
        boolean login = ftpClient.login(username, password);
        if(!login){
            log.error("登录失败, 用户名或密码错误");
            ftpClient.logout();
            ftpClient.disconnect();
            return null;
        }

        // 连接并且成功登陆ftp服务器
        log.info("login success ftp server, host:{}, port:{}, user:{}", host, port, username);

        // 设置通道字符集, 要与服务端设置一致
        ftpClient.setControlEncoding("UTF-8");
        // 设置文件传输编码类型, 字节传输:BINARY_FILE_TYPE, 文本传输:ASCII_FILE_TYPE, 建议使用BINARY_FILE_TYPE进行文件传输
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        // 动模式: enterLocalActiveMode(),被动模式: enterLocalPassiveMode(),一般选择被动模式
        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连接断开异常, 请检查");
        }

    }

    /**
     * 文件下载
     * @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;
        }

        // 中文目录处理存在问题, 转化为ftp能够识别中文的字符集
        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服务器中不存在,请检查", 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("{}下载异常,请检查", path);
        }

        inputStream.close();
        outputStream.close();
        bufferedInputStream.close();
        bufferedOutputStream.close();

        // 关闭流之后必须执行,否则下一个文件导致流为空
        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;
        }

        // 中文目录处理存在问题, 转化为ftp能够识别中文的字符集
        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);
        }

        // 关闭流之后必须执行,否则下一个文件导致流为空
        boolean complete = ftpClient.completePendingCommand();
        if(complete){
            log.info("文件{}上传完成", remotePath);
        }else{
            log.error("文件{}上传失败", remotePath);
        }


    }
}

3、测试连接、上传文件、下载文件、关闭连接功能

@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);

    }


}

经过测试,能够正常连接上ftp服务器,并且上传下载文件,最后关闭连接。

四、遇到的问题

在使用过程中,遇到以下问题,需要记录一下,以防下次忘记:

就是在创建完一个FtpClient连接之后,关闭连接之前,第一次进行文件上传或下载是正常的,当第二次进行文件上传或下载时,从FtpClient获取的输入流或输出流是空的。需要在每次操作完文件上传或下载时,添加上以下代码片段:

// 关闭流之后必须执行,否则下一个文件导致流为空
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.

百度翻译大致意思应该是:有一些FTPClient方法不能完成完成事务的整个FTP命令序列。这些命令需要程序员在接收到肯定的中间命令后采取一些行动。程序员的代码完成其操作后,必须调用此方法以从服务器接收完成回复,并验证整个事务的成功。

这里不知道是不是描述的我这种情况, completePedingCommand的意思是完成挂起命令。可能我们当前场景就符合。刚兴趣的小伙伴可以深入去探讨一下。

五、参考连接

https://blog.csdn.net/AndyWei147/article/details/90745518

https://blog.csdn.net/weixin_39981289/article/details/128614774文章来源地址https://www.toymoban.com/news/detail-468243.html

到了这里,关于Java从ftp服务器上传与下载文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • lua 请求ftp服务器数据,下载文件

    1、装入ftp库 2、调用ftp的get()方法 3、get()方法参数格式: 4、将返回到的数据写入文件中 例如,本次获取专利数据系统 http://patdata1.cnipa.gov.cn/ 的ftp站点数据

    2024年02月16日
    浏览(25)
  • Java 获取远程ftp服务器的文件

    最近做医疗的项目,涉及远程访问医院的pacs服务器获取医疗影像数据。由于医院厂商只提供了ftp的相关信息。需要用java开发脚本来自动拉取T-1的数据。 涉及jar包 ### main函数 其中涉及的配置类 ftp client连接server端 通过上面的代码实现自动拉取ftp服务端应用目录下面的文件(也

    2024年02月11日
    浏览(38)
  • Java 两台服务器间使用FTP进行文件传输

    背景:需要把服务器A中的文件拷贝至服务器B中,要求使用FTP进行传输,当文件传输未完成时文件是tmp格式的,传输完毕后显示为原格式(此处是grib2)。

    2024年02月15日
    浏览(30)
  • 纯nginx制作文件上传下载服务器

    webdav 是一组超文本传输协议的技术集合,有利于用户键协同编辑和管理存储在万维网服务器文档。同时来说就是,webdav可以让用户直接存储,下载,编辑文件,操作文件需要进行用户认证 需要的环境 linux上需要下载git(用来拉取镜像) nginx版本为:nginx-1.22.0.tar.gz 至此,需要

    2024年02月15日
    浏览(33)
  • mac PyCharm 上传文件到远程服务器+远程服务器下载到本地

    选择SFTP name:test6 输入ssh账号和密码。保存密码和30s心跳。 Local path(本地mac机器):/Users/clevercode/PycharmProjects/test6 Root path(远程服务机器):/home/clevercode/test6 Root path(远程服务机器):/home/clevercode/test6 [2024/1/18, 10:56 AM] Upload file ‘/Users/clevercode/PycharmProjects/test6/f100.py’ t

    2024年01月19日
    浏览(70)
  • Spring MVC异步上传、跨服务器上传和文件下载

    之前的上传方案,在上传成功后都会跳转页面。而在实际开发中,很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如:上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。 编写JSP页面,引入jQuery和jQuery表单上传工具jquery.form.js【该js文件已经

    2024年02月16日
    浏览(31)
  • MobaXterm上传下载文件、文件夹到服务器上

      首先通过SSH与服务器建立连接,不懂的可查阅相关资料,CSDN里有很多介绍。 1、上传下载文件 可以在命令输入窗口,无需输入命令,按ctrl单击的同时鼠标右键出现以下左图,选择receive file using Z-modem或者send file using Z-modem来上传或者下载文件。 也可以通过mobaxterm左侧的导

    2024年02月11日
    浏览(33)
  • java通过FTP跨服务器动态监听读取指定目录下文件数据

    1、文件数据在A服务器(windows)(不定期在指定目录下生成),项目应用部署在B服务器(Linux); 2、项目应用在B服务器,监听A服务器指定目录,有新生成文件,进行读取文件信息,持久化数据; 3、提供两块内容,第一安装windows FTP服务;第二项目源码,希望可以帮助到你

    2024年02月03日
    浏览(41)
  • 怎么用SecureCRT从Linux服务器上传、下载文件?

    我们在使用linux的过程中,不论是为了安装相关软件,还是其它目的,都可能需要上传或者下载linux上的文件。这里演示一下在SecureCRT中向linux上传和下载文件。 1、前言 需要上传或者下载,需要使用rz和sz命令。如果linux上没有这两个命令工具,则需要先安装(可以使用yum安装

    2024年02月04日
    浏览(36)
  • 用mac终端给Linux服务器上传、下载文件

    一、 (1)打开终端,在shell菜单下找到:\\\"新建远程连接\\\"。 (2)在\\\"新建远程连接\\\"下,找到\\\"安全文件传输(sftp)\\\"。  (3)新建新的IP,输入用户,点击\\\"连接\\\",输入密码,进入sftp传输界面。 (4) 上传mac本地文件至Linux服务器:put localfiledirectory remotefiledirectory 下载Linux服务器

    2024年02月16日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包