Java中实现ftp下载文件至本地(详细)

2023-11-16

Java中实现ftp下载文件至本地(详细):

欢迎关注蚕豆公众号,不定时分享技术。同时欢迎加入蚕豆技术群哦,扫描公众号点击关于作者加群~~~~

在这里插入图片描述

2020-09-13:今天记录一下java中实现ftp下载文件至本地的功能模块,同此与大家交流分享有什么不对的地方大家可以指出!

1.FTP协议:

什么是FTP呢?FTP 是 TCP/IP 协议组中的协议之一,是英文File Transfer Protocol的缩写。 该协议是Internet文件传送的基础,它由一系列规格说明文档组成,目标是提高文件的共享性,提供非直接使用远程计算机,使存储介质对用户透明 和可靠高效地传送数据。简单的说,FTP就是完成两台计算机之间的拷贝,从远程计算机拷贝文件至自己的计算机上,称之为“下载 (download)”文件。若将文件从自己计算机中拷贝至远程计算机上,则称之为“上载(upload)”文件。

2.SSH工具

ssh---ftp----winscp----filezilla-----xftp----

上面呢简单介绍下ftp协议和一些使用的工具,这篇文章呢我在java中是用的sftp下载,那使用的类是ChannelSftp,言归正传,奉上自己的demo。。。。

呵呵

1.连接

 protected static Logger log = LoggerFactory.getLogger(FTPUtil.class);

    public static final String NO_FILE = "No such file";

    private ChannelSftp sftp = null;

    private Session sshSession = null;

    /* FTP账号 */
    private String username;
    /* FTP密码 */
    private String password;
    /* FTP主机 */
    private String host;
    /* FTP端口 */
    private int port;

    public FTPUtil(String host, int port, String username, String password) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    /**
     * 连接sftp服务器
     *
     * @return ChannelSftp sftp类型
     * @throws Exception
     */
    public ChannelSftp connect() throws FtpException {
        log.info("尝试连接FTP {host=" + host + ",username=" + username + ",port=" + port + "}");
        boolean connect = false;
        JSch jsch = new JSch();
        try {
            int tryCountAll = 5;
            int tryCount = 0;
            while (tryCount++ < tryCountAll && !connect) {
                if (tryCount > 1) {
                    try {
                        Thread.sleep(5000 * (tryCount - 1));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    log.info("第" + tryCount + "次尝试连接FTP服务器");
                }
                sshSession = jsch.getSession(username, host, port);
                sshSession.setPassword(password);
                Properties properties = new Properties();
                properties.put("StrictHostKeyChecking", "no");
                sshSession.setConfig(properties);
                sshSession.connect(50000);
                Channel channel = sshSession.openChannel("sftp");
                channel.connect(50000);
                sftp = (ChannelSftp) channel;
                if (sftp == null) {
                    log.info("FTP 服务器未连接");
                    connect = false;
                } else {
                    log.info("连接 FTP 成功!");
                    connect = true;
                }
            }
        } catch (JSchException e) {
            throw new FtpException("连接 FTP 异常 : " + e.getMessage());
        }
        return sftp;
    }

这一块呢我们走完了第一步,先去连接远程,代码中加了重试的逻辑(重新连接的意思),代码中一些类大家可以下去自行了解,本人就不啰嗦了哦(我这边使用的是ChannelSftp ,大家不妨可以试试另一个FtpClient这个类(大步骤都差不多)

2.批量下载(我这里就不啰嗦很多了直接贴了代码,大家可以搜其他的,比如删除,单个下载什么的有很多,我这里项目用到的是一个批量下载,所以就贴出了一段代码!

public void createDirectoryQuietly(File file) {
        if (file != null) {
            if (!file.exists()) {
                if (!file.mkdirs()) {
                    throw new RuntimeException(file.getName() + " is invalid,can't be create directory");
                }
            }
        }
    }

	//remoteDir 是FTP上要下载的目录
	// localFile 是下载的本地目录
    public File downloadFileNew(String remoteDir, String localFile) throws FtpException {
        long startTime = System.currentTimeMillis();
        connect();  //连接ftp
        log.info("开始下载文件FTP目录 " + remoteDir + " 本地文件 " + localFile);
        File file = null;
        file = new File(localFile);
       /* if (file.exists()) {

            deleteFileAll(file);
        }
        file.mkdirs();*/
        createDirectoryQuietly(file);//创建目录文件,(这个方法可以创建目录,但多层级的我没试,大家定义路径的时候可以 /home/test  home是本来就有的test会创建)
        OutputStream output = null;
        try {

            /***
             * 得到custInfo路径下所有文件名
             */
            sftp.cd(remoteDir);  //进入remoteDir目录
            String path = remoteDir + "/custInfo";
            Vector v = sftp.ls(path);   //获取custInfo下文件列表
            List<String> filenameNew = new ArrayList<>(); //获取custInfo下所有目录文件名
            if (v.size() > 0) {
                log.info("文件个数不为0,开始下载。。。。。。。。。filesize=" + v.size());
                Iterator it = v.iterator();
                while (it.hasNext()) {   //循环文件
                    ChannelSftp.LsEntry lsentry = (ChannelSftp.LsEntry) it.next();
                    String filenames = lsentry.getFilename();
                    if (!".".equals(filenames) && !"..".equals(filenames)) {
                        log.info(path + "路径下的文件名" + filenames);
                        filenameNew.add(filenames);
                    }
                }
            } else {
                log.info("获取文件失败 " + remoteDir + "文件数为0");
                throw new FtpException("获取文件失败 " + remoteDir + "文件数为0");
            }

            /***
             * 得到custInfo/路径下各个文件下的文件名
             */
            sftp.cd(path);  //切换到custInfo/路径下
            for (int i = 0; i < filenameNew.size(); i++) {  //得到每个目录文件下的文件
                System.out.println(filenameNew.get(i) + "文件名");
                Vector<?> vNew = sftp.ls(filenameNew.get(i));  //获取文件列表
                sftp.cd(filenameNew.get(i)); //切换到custInfo/路径下各个文件路径下
                File file2=new File(localFile+"/"+filenameNew.get(i));
                if (file2.exists()) {
                    file2.delete();
                }
                file2.mkdir();
                if (vNew.size() > 0) {
                    Iterator it = vNew.iterator();
                    while (it.hasNext()) {
                        ChannelSftp.LsEntry lsentry = (ChannelSftp.LsEntry) it.next();
                        String filenames1 = lsentry.getFilename();
                        if (!".".equals(filenames1) && !"..".equals(filenames1)) {
                            log.info(filenameNew.get(i) + "路径下的文件名" + filenames1);
                            File file1 = new File(file2+"/"+filenames1);
                            file1.createNewFile();
                            output = new FileOutputStream(file1);
                            sftp.get(filenames1, output);
                            log.info("文件:" + filenames1 + " 下载成功.");
                        }
                    }
                    sftp.cd(path);  //每次路径下载后再切换到 上一级目录
                }
            }
        } catch (SftpException e) {
            if (e.toString().equals(NO_FILE)) {
                log.info("下载文件失败");
                throw new FtpException("下载文件失败");
            }
            throw new FtpException("ftp目录或者文件异常,检查ftp目录和文件" + e.toString());
        } catch (FileNotFoundException e) {
            throw new FtpException("本地目录异常,请检查" + file.getPath() + e.getMessage());
        } catch (IOException e) {
            throw new FtpException("创建本地文件失败" + file.getPath() + e.getMessage());
        } finally {
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    throw new FtpException("Close stream error." + e.getMessage());
                }
            }
            disconnect();
        }
        log.info("下载文件结束 耗时:" + (System.currentTimeMillis() - startTime) + " ms");
        return file;
    }

给大家解释下代码

在这里插入图片描述

第一句 sftp.cd()这个方法大家都知道,cd进去目录(注意:关键点大家注意一下:当你想操作某个目录文件时一定要cd到这个目录下(啰嗦,跟谁不知道一样

第三句 sfpt.ls()这个方法,大家也都知道哈,查看文件。往后代码的话就是使用循环将目录下的文件名循环出来,我这边使用list集合存了起来(注意:因为我当时要取得文件是 多层级目录的大家如果不是多层级的话,直接走你逻辑就好。)

在这里插入图片描述
这样的多层级目录的!

第二段代码

在这里插入图片描述
这一段呢,顾名思义,因为我的第一段代码呢是获取多层级的目录名字,那么这一段就是获取多层级目录下的文件。注意:上面代码的最后一段 那个cd方法。操作多层级目录你每进去一个目录,然后换另一个的话你就要在代码里,在cd下一个目录路径!

今天的这个ftp下载分享完了,大家如果有什么不太懂的地方,欢迎评论提出,我这会秒回哦!也谢谢大家的支持!记录生活,记录知识!我是王不正

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中实现ftp下载文件至本地(详细) 的相关文章

  • 在java中轮询Http服务器(重复发送http get请求)

    当对其进行 REST 调用时 我的 Web 服务器会发送一些信息 我想不断轮询该服务器 间隔5秒后重复发送HTTP GET请求 以检查返回的信息是否有任何变化 做到这一点最有效的方法是什么 您能提供一些代码示例吗 请注意 我只想开发客户端代
  • 我是否需要安装 SQLite 才能使 SQLiteJDBC 正常工作?

    我想我只是没有 明白 如果我的计算机上尚未安装 SQLite 并且我想编写一个使用嵌入式数据库的 Java 应用程序 并且我将 SQLiteJDBC JAR 下载 导入到我的项目中 那么这就是我所需要的吗 或者 我是否需要先安装 SQLit
  • Netbeans 8.1 Gnome 3 GTK+ UI 字体和选项卡高度

    我刚刚在运行 GNOME 3 桌面的 Ubuntu 16 04 上安装了 NetBeans 8 1 如果可能的话 我想继续使用 IDE 的 GTK 外观和感觉 但 UI 上的字体 尤其是选项卡中的字体 太小且重叠 我尝试添加 fontsiz
  • Java:扩展类并实现具有相同方法的接口

    可能无法完成以下操作 我收到编译错误 继承的方法 A doSomthing int 无法隐藏 B 中的公共抽象方法 public class A int doSomthing int x return x public interface
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • 垃圾收集器如何在幕后工作来收集死对象?

    我正在阅读有关垃圾收集的内容 众所周知 垃圾收集会收集死亡对象并回收内存 我的问题是 Collector 如何知道任何对象已死亡 它使用什么数据结构来跟踪活动对象 我正在研究这个问题 我发现GC实际上会跟踪活动对象 并标记它们 每个未标记的
  • 与 Eclipse 中的 Java Content Assist 交互

    作为我的插件项目的一部分 我正在考虑与 Eclipse 在 Java 文件上显示的内容辅助列表进行交互 我正在尝试根据一些外部数据对列表进行重新排序 我看过一些有关创建新内容辅助的教程 但没有看到有关更改现有内容辅助的教程 这可能吗 如果是
  • Java 的支持向量机?

    我想用Java编写一个 智能监视器 它可以随时发出警报detects即将到来的性能问题 我的 Java 应用程序正在以结构化格式将数据写入日志文件
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • 如何在 Java 中向时间戳添加/减去时区偏移量?

    我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多 但我仍然无法解决我面临的问题 假设我得到了格式化的Timestamp在格林威治标准时间 UTC 我的服务器位于某处 假设它设置为Asia Calcu
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • 提供节点名或服务名,或未知 Java

    最近我尝试运行我的 Java 项目 每当我运行它并将其打开到我得到的服务器地址时 Unable to determine host name java net UnknownHostException Caused by java net
  • Android 无法解析日期异常

    当尝试解析发送到我的 Android 客户端的日期字符串时 我得到一个无法解析的日期 这是例外 java text ParseException 无法解析的日期 2018 09 18T00 00 00Z 位于 偏移量 19 在 java t
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 轻松的反应

    我有一个与这里描述的类似的案例 动态更改RESTEasy服务返回类型 https stackoverflow com questions 3786781 dynamically change resteasy service return
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho

随机推荐

  • 正则表达式大全

    1 匹配中文 u4e00 u9fa5 2 英文字母 a zA Z 3 数字 0 9 4 匹配中文 英文字母和数字及下划线 u4e00 u9fa5 a zA Z0 9 同时判断输入长度 u4e00 u9fa5 a zA Z0 9 4 10 5
  • (Java)leetcode-236 Lowest Common Ancestor of a Binary Tree(二叉树的最近公共祖先)

    题目描述 给定一个二叉树 找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为 对于有根树 T 的两个结点 p q 最近公共祖先表示为一个结点 x 满足 x 是 p q 的祖先且 x 的深度尽可能大 一个节点也可以是它自己的
  • MTK多国语言相关经验总结

    MTK多国语言相关经验总结 一 移植多国语言移植多国语言主要牵涉到对mmi features h 整个工程的宏控定义文件 fontres c 字体资源文件 的修改 并添加相应的字库文件 1 语言宏控的修改在mmi features h文件中
  • 使用C#语言,基于OpenCvSharp 开发摄像头后台,移动物体位置识别 (一)

    刚刚入门OpenCvSharp 也是小白一枚 教程很少 慢慢摸索 边学边记录 文末附链接 效果 要求 Visual Studio 2017 摄像头x1 准备工作 新建一个 Net Framework 控制台应用 右击解决方案 gt 管理解决
  • 京城游戏人-Day13: 获取被点击的 Button 以及其上的文字内容

    京城游戏人 Day13 获取被点击的 Button 以及其上的文字内容 作者 大锐哥 地址 http blog csdn net prevention 获取被点击的 button var button UnityEngine EventSy
  • Centos + docker,Ubuntu + docker介绍安装及详细使用

    docker笔记 常用命令 设置docker开机自启 sudo chkconfig docker on 查所有镜像 docker images 删除某个镜像 docker rmi CONTAINER ID 容器ID 删除所有镜像 docke
  • Linux命令大全!

    系统信息 arch 显示机器的处理器架构 1 uname m 显示机器的处理器架构 2 uname r 显示正在使用的内核版本 dmidecode q 显示硬件系统部件 SMBIOS DMI hdparm i dev hda 罗列一个磁盘的
  • Grid 布局实现九宫格图片动画

    前言 Grid 布局实现九宫格 background position设置背景图像起始位置 速速来Get吧 文末分享源代码 记得点赞 关注 收藏 1 实现效果 2 实现步骤 定义css变量 九宫格中每个宫格的长 宽为w 宫格之间的间距为ga
  • STL容器的线程安全

    众所周知 STL容器不是线程安全的 对于vector 即使写方 生产者 是单线程写入 但是并发读的时候 由于潜在的内存重新申请和对象复制问题 会导致读方 消费者 的迭代器失效 实际表现也就是招致了core dump 另外一种情况 如果是多个
  • firefox os_如何在电视上测试Firefox OS应用

    firefox os One of my responsibilities in my new role in Partner Engineering at Mozilla is testing HTML5 powered apps and
  • 解决git中出现的“bash syntax error near unexpected token ’(‘”错误

    今天来分享一篇关于我在git使用过程中出现的一个错误 错误信息 bash syntax error near unexpected token 翻译过来就是提示我在 这里有错误 而这个错误是我在使用git commit提交时候产生的 我当时
  • 4. Docker 构建镜像

    Docker 构建镜像 docker制作镜像通常是通过两种方式来实现的 第一种是通过容器的 commit 第二种是通过 Buildfile来实现的 docker commit 打包镜像 容器在运行过程中我们难免会做一些修改 比如运行的mys
  • 程序框架---缩进(Python)

    缩进 类定义 函数定义 选择结构 循环结构 with块 行尾的冒号表示缩进的开始 python程序是依靠代码块的缩进来体现代码之间的逻辑关系的 缩进结束就表示一个代码块结束了 同一级别代码块的缩进量必须相同 一般而言 以4个空格或一个TAB
  • OLED透明屏:在广告领域中的应用,为品牌注入更强的视觉冲击

    OLED透明屏作为一项引人注目的技术创新 其独特的透明度和高清晰度为各行各业带来了全新的展示和创意空间 本文将详细介绍其透明度 高对比度 超薄柔性设计以及强大的颜色表现力 并探讨其在零售 汽车和建筑等领域的应用前景 一 透明度 开启全新的透
  • 聊透spring @Configuration配置类

    本章节我们来探索Spring中一个常用的注解 Configuration 我们先来了解一下该注解的作用是 用来定义当前类为配置类 那啥是配置类啊 有啥用啊 这个我们得结合实际使用场景来说 通常情况下 加了 Configuration的配置类
  • 机器学习——决策树(Decision Trees)

    决策树 决策树是机器学习中一种最为常见的算法 顾名思义 决策树是基于树结构来进行决策的 这恰是人类在面对决策问题时一种很自然的处理机制 决策树的生成算法可以说是信息论的一种应用 但它其实只用到了信息论中的一小部分思想 因此对信息论有个基础性
  • Python系列教程-目录

    转载至 http www cricode com 3086 html Python初级教程 Python快速教程 手册 Python基础01 Hello World Python基础02 基本数据类型 Python基础03 序列 Pytho
  • CSS 之层叠规则(权级、权重、顺序)详解

    文章目录 参考 描述 定义 层叠 层叠与冲突 规则 权重 优先级 权重值的叠加 顺序 权级 权级 层叠规则的运用 顺序 尾声 参考 项目 描述 MDN WEB Docs 优先级 Amily mo 令人烦恼的css选择器权值问题 Amily
  • 《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输

    1 基于TCP实现字符串对话 主要需求 服务器端和客户端各传递 1 次字符串 基于 TCP 协议 传递字符串前先以 4 字节整数型方式传递字符串长度 剩余部分为字符串数据 注 下面的代码基于 Windows 系统实现 1 1 服务器端 gc
  • Java中实现ftp下载文件至本地(详细)

    Java中实现ftp下载文件至本地 详细 欢迎关注蚕豆公众号 不定时分享技术 同时欢迎加入蚕豆技术群哦 扫描公众号点击关于作者加群 2020 09 13 今天记录一下java中实现ftp下载文件至本地的功能模块 同此与大家交流分享有什么不对