Java下载FTP服务器上的资源,附带FTP工具类

通过xftp可以看到目标服务器上面的资源如下:
在这里插入图片描述

第一步:导入ftp依赖:

		 <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.7</version> <!-- 使用最新版本 -->
        </dependency>

首先是通过原生代码来操作:
这里有个坑:如果是匿名登录,账号密码还是要的String username = "anonymous"即可,密码随意,直接上代码:

下载文件操作:

import com.example.demo.test1.utils.FtpUtil;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class test8 {

    public static void main(String[] args) throws Exception {
        String server = "ftp.ncbi.nlm.nih.gov";
        int port = 21;
        String username = "anonymous";
        String password = "your_password";


        FTPClient ftpClient = new FTPClient();
        ftpClient.connect(server, port);
        ftpClient.login(username, password);

        String remoteFilePath = "/pubmed/updatefiles/pubmed24n1220.xml.gz";
        String localFilePath = "D:\\BaiduNetdiskDownload\\pubmed24n1220.xml.gz";

        //设置本地被动模式
        ftpClient.enterLocalPassiveMode();
        ftpClient.setControlEncoding("UTF-8");

        // 设置二进制文件类型
        //ftpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);

        try {
            // 创建本地文件输出流
            OutputStream outputStream = new FileOutputStream(localFilePath);

            // 从 FTP 服务器下载文件
            boolean success = ftpClient.retrieveFile(remoteFilePath, outputStream);

            if (success) {
                System.out.println("File downloaded successfully.");
            } else {
                System.out.println("File download failed.");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭 FTP 连接
            ftpClient.logout();
            ftpClient.disconnect();
        }
    }
}

这里的远端路径和需要下载的本地路径我都提前把文件名拼上去了,根据需要可以动态拼接:下载结果:
在这里插入图片描述
查看文件目录操作:查看/pubmed下的目录:
在这里插入图片描述

public class test6 {

    public static void main(String[] args) throws Exception{
        String server = "ftp.ncbi.nlm.nih.gov";
        int port = 21;
        String username = "anonymous";
        String password = "your_password";
        String remoteFilePath2 = "/pubmed";


        FTPClient ftpClient = new FTPClient();

        try {
            ftpClient.connect(server, port);
            ftpClient.login(username, password);

            // 设置本地被动模式
            ftpClient.enterLocalPassiveMode();

            // 设置二进制文件类型
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            // 切换到指定文件夹

            ftpClient.changeWorkingDirectory(remoteFilePath2);

            // 使用listDirectories()获取目录列表
            FTPFile[] ftpDirectories = ftpClient.listDirectories();
            if (ftpDirectories != null && ftpDirectories.length > 0) {
                System.out.println("子目录列表:");
                for (FTPFile ftpDirectory : ftpDirectories) {
                    System.out.println(ftpDirectory.getName());
                }
            } else {
                System.out.println("当前文件夹中没有子目录。");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭 FTP 连接
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述
查看目录下文件操作:查看/pubmed/updatefiles下的gz结尾文件
在这里插入图片描述

import com.example.demo.test1.utils.FtpUtil;
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.FTPFile;

import java.io.*;
@Slf4j
public class test5 {
    public static void main(String[] args) throws Exception {
        FTPClient ftpClient = FtpUtil.getFtpClient("ftp.ncbi.nlm.nih.gov", 21, "anonymous", "your_password");
        try {
            // 切换到指定文件夹
            String remoteFolder = "/pubmed/updatefiles";
            ftpClient.changeWorkingDirectory(remoteFolder);

            // 使用LIST命令获取详细文件列表
            String[] fileDetails = ftpClient.listNames();
            if (fileDetails != null && fileDetails.length > 0) {
                System.out.println("文件列表:");
                for (String fileDetail : fileDetails) {
                    if (fileDetail.endsWith(".gz")) {
                        System.out.println(fileDetail);
                    }
                }
            } else {
                System.out.println("文件夹为空或没有权限查看文件列表。");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭 FTP 连接
            FtpUtil.disConnect(ftpClient);
        }
    }

}

在这里插入图片描述
这里的登录退出都是使用了FtpUtil工具类,方便很多,直接上工具类代码:

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(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);
        }


    }
}

参考链接:Java从ftp服务器上传与下载文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/343450.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Portainer Docker容器可视化管理平台实践

Portainer Docker容器可视化管理平台实践 引安装登录Remote ENV 实践 引 平常用docker命令操作比较多&#xff0c;找了一款docker可视化工具&#xff0c;方便快速预览和批量操作&#xff0c;不想一行一行敲的时候&#xff0c;可以偷偷懒。Portainer试用了一下&#xff0c;安装…

Hbas简介:数据模型和概念、物理视图

文章目录 说明零 BigTable一 Hbase简介二 HBase 访问接口简介三 行式&列式存储四 HBase 数据模型4.1 HBase 列族数据模型4.2 数据模型的相关概念4.3 数据坐标 五 概念&物理视图 说明 本文参考自林子雨老师的大数据技术原理与应用(第三版)教材内容&#xff0c;仅供学习…

特斯联携手华为发布联合解决方案,助力京津冀千行百业智能升级

近日&#xff0c;特斯联受邀出席了由廊坊市人民政府主办&#xff0c;廊坊经济技术开发区管委会联合华为技术有限公司协办的河北人工智能计算中心上线仪式暨新一代信息技术高端论坛&#xff0c;在论坛上&#xff0c;华为携手特斯联等伙伴共同发布了河北人工智能计算中心联合解决…

Git--基本操作介绍(2)

Git 常用的是以下 6 个命令&#xff1a;git clone、git push、git add 、git commit、git checkout、git pull. 说明&#xff1a; workspace&#xff1a;工作区staging area&#xff1a;暂存区/缓存区local repository&#xff1a;版本库或本地仓库remote repository&#xf…

VS2019查看文件编码格式

文件->高级保存选项 在这里可以看见现在的编码格式也可以修改编码格式 如果没有高级保存选项的话可以参考这篇博客进行设置

人大金仓数据库授权文件过期解决

一台用于测试的人大金仓数据库访问失败。 登录后发现服务停了。 使用命令行启动&#xff0c;提示服务过期。 查网上资料&#xff0c;说替换原有文件可以解决。 于是去官网下载一个新的&#xff0c;替换掉原来的授权文件。 再次启动数据库&#xff0c;还是提示授权文件过期。…

leetcode:最接近的三数之和---(双指针,排序,数组)

题目&#xff1a; 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例&#xff1a; 示例 1&#xff1a; 输入&#xff1a;nums [-1…

第一堂复试

1.数据结构的基本概念 数据元素 相当于一个类 数据对象是数据元素的集合 数据项&#xff1a;具体的属性 2.数据结构三要素 1.一般线性表相当于数组&#xff0c;2.栈先进后出&#xff0c;3.队列先进先出 非线性结构一般是一对多 线性结构一般是一对一 3.数据的存储结构 4.算…

通过curl访问k8s集群获取证书或token的方式

K8S安全控制框架主要由下面3个阶段进行控制&#xff0c;每一个阶段都支持插件方式&#xff0c;通过API Server配置来启用插件。 1. Authentication&#xff08;认证&#xff09; 2. Authorization&#xff08;授权&#xff09; 3. Admission Control&#xff08;准入控制&#…

解决router重复push报错

vue-router重复push报错解决 一、报错情况二、解决1、重写push方法2、代码解释&#xff08;来自讯飞星火AI&#xff09; 一、报错情况 情况复现&#xff1a;使用router跳转时&#xff0c;router会有一个历史记录栈&#xff0c;当新的push元素和上一次最后push的元素一致&#…

对于超低延迟SSD,IO调度器已经过时了吗?-part2

为了进行这项研究&#xff0c;他们设计了一套严谨的实验方法论&#xff0c;包括在配备了高速Intel Optane P4801X Series NVMe SSD的服务器上执行一系列微观和宏观基准测试&#xff0c;同时监测系统能耗情况。这些测试涵盖了多种工作负载场景&#xff0c;从单一进程提交大量请求…

php基础学习之数据类型

php数据类型的基本概念 数据类型&#xff1a;data type&#xff0c;在PHP中指的是数据本身的类型&#xff0c;而不是变量的类型。 PHP 是一种弱类型语言&#xff0c;变量本身没有数据类型。 把变量类比成一个杯子&#xff08;容器&#xff09;&#xff0c;杯子可以装雪碧、可…

E - Souvenir(图论典型例题)

思路&#xff1a;对于有很多询问的题&#xff0c;一般都是先初始化。我们求出每个点到其他点的最短路径以及相同路径下最大的价值和即可。 代码&#xff1a; #include <bits/stdc.h> #define pb push_back #define a first #define b second using namespace std; type…

C++面试:跳表

目录 跳表介绍 跳表的特点&#xff1a; 跳表的应用场景&#xff1a; C 代码示例&#xff1a; 跳表的特性 跳表示例 总结 跳表&#xff08;Skip List&#xff09;是一种支持快速搜索、插入和删除的数据结构&#xff0c;具有相对简单的实现和较高的查询性能。下面是跳表…

排序(插入排序)

现在&#xff0c;我们学习了之前数据结构的部分内容&#xff0c;即将进入一个重要的领域&#xff1a;排序&#xff0c;这是一个看起来简单&#xff0c;但是想要理清其中逻辑并不简单的内容&#xff0c;让我们一起加油把&#xff01; 排序的概念及其运用 排序的概念 排序&…

激光雷达行业梳理1-概述、市场、技术路线

激光雷达作为现代精确测距和感知技术的关键组成部分&#xff0c;在近几年里取得了令人瞩目的发展。作为自动驾驶感知层面的重要一环&#xff0c;相较摄像头、毫米波雷达等其他传感器具有“ 精准、快速、高效作业”的巨大优势&#xff0c;已成为自动驾驶的主传感器之一&#xff…

CVHub|AI标注神器 X-AnyLabeling-v2.3.0 发布!支持YOLOv8旋转目标检测、EdgeSAM、RTMO等热门模型!

本文来源公众号“CVHub”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;AI标注神器 X-AnyLabeling-v2.3.0 发布&#xff01;支持YOLOv8旋转目标检测、EdgeSAM、RTMO等热门模型&#xff01; 今天主要为大家详细介绍 X-AnyLabeling …

NQA测试机制—UDP Jitter测试

概念 UDP Jitter是以UDP报文为承载&#xff0c;通过记录在报文中的时间戳信息来统计时延、抖动、丢包的一种测试方法。Jitter&#xff08;抖动时间&#xff09;是指相邻两个报文的接收时间间隔减去这两个报文的发送时间间隔。 UDP Jitter测试的过程如下&#xff1a; 1. 源端&a…

【大数据处理技术实践】期末考查题目:集群搭建、合并文件与数据统计可视化

集群搭建、合并文件与数据统计可视化 实验目的任务一&#xff1a;任务二&#xff1a; 实验平台实验内容及步骤任务一&#xff1a;搭建具有3个DataNode节点的HDFS集群集群环境配置克隆的方式创建 Slave 节点修改主机名编辑 hosts 文件生成密钥免认证登录修改 hadoop 的配置文件编…

软件测试面试题(完整版)

1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&#xff0c;可以实现跨平台&#xff0c;客户端零维护&#xff0c;维护成本低&#xff0c;但是个性化能力低&#xff0c;响应速度较慢 C/S响应速度快&#xff0c;安全性强&#xff0c;一般应用于局域网中&#xff0c…