`
IThead
  • 浏览: 428146 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基于ftp4j的FTP客户端工具

    博客分类:
  • Java
阅读更多
ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分功能。可以将ftp4j嵌到你的Java应用中,来传输文件(包括上传和下载),浏览远程FTP服务器上的目录和文件,创建、删除、重命,移动远程目录和文件。ftp4j提供多种方式连接到远程FTP服务器包括:通过TCP/IP直接连接,通过FTP代理、HTTP代理、SOCKS4/4a代理和SOCKS5代理连接,通过SSL安全连接。


ftp4j该项目主页:
http://www.sauronsoftware.it/projects/ftp4j/
http://www.sauronsoftware.it/projects/ftp4j/manual.php


ftp4j这是一个基本类库,用起来有些不爽,首先是受检查异常太多太多,这是合理的,把异常留给使用者灵活处理,其次是提供的客户单API太基础,还不够强悍。下面是我针对实际中最常用的功能所作的一个工具类。


在对待异常的方式上,将检查异常全转换为运行时异常,并对一些潜在操作的错误进行检查,提供了原API中没有的一些功能,批量下载、任务侦听器、检查FTP上文件或目录是否存在以及类型。



下面是实现代码:

package lavasoft.common.ftp;

import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPFile;
import lavasoft.common.PathToolkit;

import java.io.File;
import java.util.List;

/**
* TTP客户端工具
*
* @author leizhimin 2009-11-30 10:20:17
*/
public final class FTPToolkit {

        private FTPToolkit() {
        }

        /**
         * 创建FTP连接
         *
         * @param host         主机名或IP
         * @param port         ftp端口
         * @param username ftp用户名
         * @param password ftp密码
         * @return 一个客户端
         */
        public static FTPClient makeFtpConnection(String host, int port, String username, String password) {
                FTPClient client = new FTPClient();
                try {
                        client.connect(host, port);
                        client.login(username, password);
                } catch (Exception e) {
                        throw new FTPRuntimeException(e);
                }
                return client;
        }

        /**
         * FTP下载文件到本地一个文件夹,如果本地文件夹不存在,则创建必要的目录结构
         *
         * @param client                    FTP客户端
         * @param remoteFileName    FTP文件
         * @param localFolderPath 存的本地目录
         */
        public static void download(FTPClient client, String remoteFileName, String localFolderPath) {
                int x = isExist(client, remoteFileName);
                MyFtpListener listener = MyFtpListener.instance(FTPOptType.UP);
                File localFolder = new File(localFolderPath);
                if (localFolder.isFile()) {
                        throw new FTPRuntimeException("所要的下载保存的地方是一个文件,无法保存!");
                } else {
                        if (!localFolder.exists())
                                localFolder.mkdirs();
                }
                if (x == FTPFile.TYPE_FILE) {
                        String localfilepath = PathToolkit.formatPath4File(localFolderPath + File.separator + new File(remoteFileName).getName());
                        try {
                                if (listener != null)
                                        client.download(remoteFileName, new File(localfilepath), listener);
                                else
                                        client.download(remoteFileName, new File(localfilepath));
                        } catch (Exception e) {
                                throw new FTPRuntimeException(e);
                        }
                } else {
                        throw new FTPRuntimeException("所要下载的文件" + remoteFileName + "不存在!");
                }
        }

        /**
         * FTP上传本地文件到FTP的一个目录下
         *
         * @param client                     FTP客户端
         * @param localfile                本地文件
         * @param remoteFolderPath FTP上传目录
         */
        public static void upload(FTPClient client, File localfile, String remoteFolderPath) {
                remoteFolderPath = PathToolkit.formatPath4FTP(remoteFolderPath);
                MyFtpListener listener = MyFtpListener.instance(FTPOptType.UP);
                try {
                        client.changeDirectory(remoteFolderPath);
                        if (!localfile.exists()) throw new FTPRuntimeException("所要上传的FTP文件" + localfile.getPath() + "不存在!");
                        if (!localfile.isFile()) throw new FTPRuntimeException("所要上传的FTP文件" + localfile.getPath() + "是一个文件夹!");
                        if (listener != null)
                                client.upload(localfile, listener);
                        else
                                client.upload(localfile);
                        client.changeDirectory("/");
                } catch (Exception e) {
                        throw new FTPRuntimeException(e);
                }
        }

        /**
         * FTP上传本地文件到FTP的一个目录下
         *
         * @param client                     FTP客户端
         * @param localfilepath        本地文件路径
         * @param remoteFolderPath FTP上传目录
         */
        public static void upload(FTPClient client, String localfilepath, String remoteFolderPath) {
                File localfile = new File(localfilepath);
                upload(client, localfile, remoteFolderPath);
        }

        /**
         * 批量上传本地文件到FTP指定目录上
         *
         * @param client                     FTP客户端
         * @param localFilePaths     本地文件路径列表
         * @param remoteFolderPath FTP上传目录
         */
        public static void uploadListPath(FTPClient client, List<String> localFilePaths, String remoteFolderPath) {
                remoteFolderPath = PathToolkit.formatPath4FTP(remoteFolderPath);
                try {
                        client.changeDirectory(remoteFolderPath);
                        MyFtpListener listener = MyFtpListener.instance(FTPOptType.UP);
                        for (String path : localFilePaths) {
                                File file = new File(path);
                                if (!file.exists()) throw new FTPRuntimeException("所要上传的FTP文件" + path + "不存在!");
                                if (!file.isFile()) throw new FTPRuntimeException("所要上传的FTP文件" + path + "是一个文件夹!");
                                if (listener != null)
                                        client.upload(file, listener);
                                else
                                        client.upload(file);
                        }
                        client.changeDirectory("/");
                } catch (Exception e) {
                        throw new FTPRuntimeException(e);
                }
        }

        /**
         * 批量上传本地文件到FTP指定目录上
         *
         * @param client                     FTP客户端
         * @param localFiles             本地文件列表
         * @param remoteFolderPath FTP上传目录
         */
        public static void uploadListFile(FTPClient client, List<File> localFiles, String remoteFolderPath) {
                try {
                        client.changeDirectory(remoteFolderPath);
                        remoteFolderPath = PathToolkit.formatPath4FTP(remoteFolderPath);
                        MyFtpListener listener = MyFtpListener.instance(FTPOptType.UP);
                        for (File file : localFiles) {
                                if (!file.exists()) throw new FTPRuntimeException("所要上传的FTP文件" + file.getPath() + "不存在!");
                                if (!file.isFile()) throw new FTPRuntimeException("所要上传的FTP文件" + file.getPath() + "是一个文件夹!");
                                if (listener != null)
                                        client.upload(file, listener);
                                else
                                        client.upload(file);
                        }
                        client.changeDirectory("/");
                } catch (Exception e) {
                        throw new FTPRuntimeException(e);
                }
        }


        /**
         * 判断一个FTP路径是否存在,如果存在返回类型(FTPFile.TYPE_DIRECTORY=1、FTPFile.TYPE_FILE=0、FTPFile.TYPE_LINK=2)
         * 如果文件不存在,则返回一个-1
         *
         * @param client         FTP客户端
         * @param remotePath FTP文件或文件夹路径
         * @return 存在时候返回类型值(文件0,文件夹1,连接2),不存在则返回-1
         */
        public static int isExist(FTPClient client, String remotePath) {
                remotePath = PathToolkit.formatPath4FTP(remotePath);
                int x = -1;
                FTPFile[] list = null;
                try {
                        list = client.list(remotePath);
                } catch (Exception e) {
                        return -1;
                }
                if (list.length > 1) return FTPFile.TYPE_DIRECTORY;
                else if (list.length == 1) {
                        FTPFile f = list[0];
                        if (f.getType() == FTPFile.TYPE_DIRECTORY) return FTPFile.TYPE_DIRECTORY;
                        //假设推理判断
                        String _path = remotePath + "/" + f.getName();
                        try {
                                int y = client.list(_path).length;
                                if (y == 1) return FTPFile.TYPE_DIRECTORY;
                                else return FTPFile.TYPE_FILE;
                        } catch (Exception e) {
                                return FTPFile.TYPE_FILE;
                        }
                } else {
                        try {
                                client.changeDirectory(remotePath);
                                return FTPFile.TYPE_DIRECTORY;
                        } catch (Exception e) {
                                return -1;
                        }
                }
        }

        /**
         * 关闭FTP连接,关闭时候像服务器发送一条关闭命令
         *
         * @param client FTP客户端
         * @return 关闭成功,或者链接已断开,或者链接为null时候返回true,通过两次关闭都失败时候返回false
         */

        public static boolean closeConnection(FTPClient client) {
                if (client == null) return true;
                if (client.isConnected()) {
                        try {
                                client.disconnect(true);
                                return true;
                        } catch (Exception e) {
                                try {
                                        client.disconnect(false);
                                } catch (Exception e1) {
                                        e1.printStackTrace();
                                        return false;
                                }
                        }
                }
                return true;
        }
}



package lavasoft.common;

import java.io.File;

/**
* 路径处理工具,操作系统自适应
*
* @author leizhimin 2009-11-30 16:01:34
*/
public final class PathToolkit {
        private PathToolkit() {
        }

        /**
         * 格式化文件路径,将其中不规范的分隔转换为标准的分隔符,并且去掉末尾的文件路径分隔符。
         * 本方法操作系统自适应
         *
         * @param path 文件路径
         * @return 格式化后的文件路径
         */
        public static String formatPath4File(String path) {
                String reg0 = "\\\\+";
                String reg = "\\\\+|/+";
                String temp = path.trim().replaceAll(reg0, "/");
                temp = temp.replaceAll(reg, "/");
                if (temp.length() > 1 && temp.endsWith("/")) {
                        temp = temp.substring(0, temp.length() - 1);
                }
                temp = temp.replace('/', File.separatorChar);
                return temp;
        }

        /**
         * 格式化文件路径,将其中不规范的分隔转换为标准的分隔符
         * 并且去掉末尾的"/"符号(适用于FTP远程文件路径或者Web资源的相对路径)。
         *
         * @param path 文件路径
         * @return 格式化后的文件路径
         */
        public static String formatPath4FTP(String path) {
                String reg0 = "\\\\+";
                String reg = "\\\\+|/+";
                String temp = path.trim().replaceAll(reg0, "/");
                temp = temp.replaceAll(reg, "/");
                if (temp.length() > 1 && temp.endsWith("/")) {
                        temp = temp.substring(0, temp.length() - 1);
                }
                return temp;
        }

        /**
         * 获取FTP路径的父路径,但不对路径有效性做检查
         *
         * @param path FTP路径
         * @return 父路径,如果没有父路径,则返回null
         */
        public static String genParentPath4FTP(String path) {
                String pp = new File(path).getParent();
                if (pp == null) return null;
                else return formatPath4FTP(pp);
        }
}



package lavasoft.common.ftp;

/**
* FTP操作类型
*
* @author leizhimin 2009-11-30 11:16:59
*/
public enum FTPOptType {
        UP("上传"),
        DOWN("下载"),
        LIST("浏览"),
        DELFILE("删除文件"),
        DELFOD("删除文件夹"),
        RENAME("上传");

        private String optname;

        FTPOptType(String optname) {
                this.optname = optname;
        }

        public String getOptname() {
                return optname;
        }
}



package lavasoft.common.ftp;

import it.sauronsoftware.ftp4j.FTPDataTransferListener;

/**
* FTP监听器,做了简单实现,可以使用commons logger替换System.out.println
*
* @author leizhimin 2009-11-30 11:05:33
*/
public class MyFtpListener implements FTPDataTransferListener {
        private FTPOptType optType;

        public static MyFtpListener instance(FTPOptType optType) {
                return new MyFtpListener(optType);
        }

        private MyFtpListener(FTPOptType optType) {
                this.optType = optType;
        }

        public void started() {
                System.out.println(optType.getOptname() + ":FTP启动喽。。。。。。");
        }

        public void transferred(int length) {
                System.out.println(optType.getOptname() + ":FTP传输喽。。。。。。");

        }

        public void completed() {
                System.out.println(optType.getOptname() + ":FTP完成喽。。。。。。");
        }

        public void aborted() {
                System.out.println(optType.getOptname() + ":FTP中止喽。。。。。。");
        }

        public void failed() {
                System.out.println(optType.getOptname() + ":FTP挂掉喽。。。。。。");
        }
}



package lavasoft.common.ftp;

/**
* FTP异常
*
* @author leizhimin 2009-11-30 10:28:03
*/
public class FTPRuntimeException extends RuntimeException {
        public FTPRuntimeException() {
                super();
        }

        public FTPRuntimeException(String message) {
                super(message);
        }

        public FTPRuntimeException(String message, Throwable cause) {
                super(message, cause);
        }

        public FTPRuntimeException(Throwable cause) {
                super(cause);
        }
}



package lavasoft;

import it.sauronsoftware.ftp4j.FTPClient;
import lavasoft.common.ftp.FTPToolkit;

/**
* 简单测试下
*
* @author leizhimin 2009-11-30 12:25:42
*/
public class Test {
        public static void main(String args[]) throws Exception {
                String ftpip = "192.168.104.113";
                int ftpport = 21;
                String ftpuser = "vcomkp.ftpadmin";
                String ftppswd = "ftp";

                FTPClient client = FTPToolkit.makeFtpConnection(ftpip, ftpport, ftpuser, ftppswd);
                FTPToolkit.upload(client, "C:\\Dynamicclrr4.zip", "/aaa/bbb/ccc");
                FTPToolkit.download(client, "/Dynamicclrr4.zip", "D:\\");
                FTPToolkit.closeConnection(client);
        }
}



上传:FTP启动喽。。。。。。
上传:FTP传输喽。。。。。。
上传:FTP传输喽。。。。。。
上传:FTP完成喽。。。。。。
上传:FTP启动喽。。。。。。
上传:FTP传输喽。。。。。。
上传:FTP传输喽。。。。。。
上传:FTP完成喽。。。。。。

Process finished with exit code 0




本程序在RedHat AS 5上使用vsftpd测试通过,一般来说windows下测试通过的ftp工具,一般在Linux下通不过,因为Windows没有太多权限控制。而Linux控制非常严格,常常因为没有权限而导致操作失败,这时候,要对Linux的FTP用户给读写的权限才能正确执行以上代码。


另外说明一点,在判断ftp服务器上一个文件是否存在的isExist方法,具有一定一个局限性,体现在两方面:一是对特定组件版本的依赖性,不同版本list等方法实现不同,对错误路径的处理也不同。二是,不同的ftp服务器对发送list命令反馈的结果不尽相同。



这也是为什么很多ftp组件工具不去实现isExist的方法。对使用本方法测试有异常不符合事实的情况下,需要根据特定的环境测试重新实现isExist方法即可。



这里我给出了一个测试:

我用的vsftp目录结构如下

/aaa

/aaa/bbb/ccc

/aaa/bbb/ccc/Dynamicclrr4.zip



调用方法测试:

                System.out.println(FTPToolkit.isExist(client, "/aaa/bbb/ccc"));                                    //目录
                System.out.println(FTPToolkit.isExist(client, "/aaa/bbb/ccc/Dynamicclrr4.zip")); //文件
                System.out.println(FTPToolkit.isExist(client, "/aaa/bbb/ccc/xxxxxx.zip"));             //不存在的文件
                System.out.println(FTPToolkit.isExist(client, "/aaa/bbb/pppppdd"));                            //不存在的目录




1
0
-1
-1

Process finished with exit code 0



可见,打印的结果与实际情况相符。

分享到:
评论

相关推荐

    j-ftp 客户端

    J-FTP客户端是一款基于Java语言开发的多功能文件传输工具。它不仅能够通过FTP(File Transfer Protocol)进行文件的上传与下载,还能支持其他多种协议,如SMB(Server Message Block)、SFTP(Secure File Transfer ...

    基于Java的源码-FTP客户端Java类库 ftp4j.zip

    总之,`ftp4j`是Java开发中实现FTP客户端功能的一个强大工具,它的易用性和全面的功能使得它在许多项目中被广泛采用。通过深入学习和实践,开发者可以充分利用这个库来实现高效、可靠的FTP通信。

    基于Java的FTP客户端Java类库 ftp4j.zip

    Java FTP客户端库ftp4j是Java开发者用于实现FTP(文件传输协议)功能的强大工具。FTP是一种广泛用于在网络上上传、下载文件的标准协议。FTP4j是一个开源的Java库,由Sergio Bossa开发,它提供了丰富的API,使开发者...

    基于Java的实例开发源码-FTP客户端Java类库 ftp4j.zip

    Java FTP客户端库ftp4j是Java开发者用于实现FTP(文件传输协议)功能的强大工具。它提供了丰富的API,使得开发者能够方便地与FTP服务器进行交互,包括上传、下载、列出目录内容、创建和删除文件及目录等操作。在这个...

    Java常用FTP文件操作说明Apache.FTPClient,ftp4j,jftp

    而Apache.FTPClient就是基于此工具包提供的FTP客户端功能。 ##### 连接与登录 示例代码中展示了一个名为`FTPCommon`的类,该类主要用于封装FTP相关的操作。以下是对该类部分代码的分析: 1. **类定义**:`public ...

    j-ftp实现ftp

    FTP(File Transfer Protocol)是一种...总的来说,j-ftp是一个实用的Java FTP客户端,它利用了Java的AWT库创建图形界面,并实现了基本的FTP功能。对于初学者和经验丰富的开发者,它都是一个有价值的工具和学习资源。

    j-ftp:jar+源码

    J-FTP,作为一个专注于FTP(File Transfer Protocol)服务的Java库,为开发者提供了一个高效、可靠的FTP客户端工具,用于实现文件的上传和下载功能。本文将详细介绍J-FTP的核心概念、使用方法以及源码解析,帮助读者...

    FTP帮助文档

    这份“FTP帮助文档”将向我们揭示FTP的基本概念、工作原理、如何使用FTP以及FTP客户端的使用方法,例如通过“ftp4j-1.6”库进行编程操作。 FTP的工作基于TCP/IP协议栈,分为两种模式:主动模式和被动模式。主动模式...

    apache_ftp 开发包

    `slf4j-api-1.5.2.jar`和`slf4j-log4j12-1.5.2.jar`是Simple Logging Facade for Java (SLF4J)的API和Log4j绑定,SLF4J提供了一种统一的日志接口,允许开发者在不改变代码的情况下切换不同的日志实现。 在使用这个...

    stm32下的ftp服务器

    6. **调试与测试**:使用FTP客户端(如FileZilla)连接到开发板,测试上传、下载、删除文件等功能。确保一切正常工作,没有数据丢失或错误。 7. **安全考虑**:虽然这是一个基本的FTP服务器实现,但安全性是不容...

    linux ftp工具下载包

    Linux FTP工具下载包,主要包含的是FTP服务器软件的安装包,这里特别提到了`vsftpd`。`vsftpd`是"Very Secure FTP Daemon"的缩写,它是一款广泛使用的开源FTP服务器软件,尤其在Linux系统中备受青睐。本文将深入探讨...

    ftp资料,建立自己的服务端

    ### 建立个人FTP服务:Java实现批量大文件上传...总之,通过使用Java和合适的FTP客户端库,结合数字签名、数据加密等安全措施,可以构建出一套高效、安全的文件上传下载系统,满足现代工程项目中对数据传输的高要求。

    基于N32G457的FTP远程升级固件程序

    总结起来,基于N32G457的FTP远程升级固件程序涉及到FTP协议的理解,FTP客户端库的集成,固件验证机制的设计,以及安全的固件更新流程。这一过程需要对STM32单片机、ARM架构以及嵌入式系统的知识有深入理解。通过这样...

    FTP Client.zip

    总结来说,这个压缩包提供了一个基于STM32F1微控制器和W5500网络接口的FTP客户端实现,使用了Keil μVision开发环境,并且包含了项目配置、源代码、调试设置和可能的库文件。对于想要学习在嵌入式系统中实现FTP...

    linux下ftp搭建

    使用FTP客户端(如FileZilla)尝试连接到服务器,验证设置是否正确。输入服务器IP地址、用户名和密码。 9. **高级配置** 根据需求,你可能还需要设置SSL/TLS加密、限速、日志记录等高级选项。这需要修改vsftpd...

    java ftp工具

    以上就是关于“Java FTP工具”的主要知识点介绍,涵盖了从网络通信、GUI设计到文件操作等多个方面,为开发者提供了一套完整的FTP客户端解决方案。通过学习和使用这样的工具,开发者可以深入理解FTP协议和Java网络...

    FTP身份校验登录实验报告

    FTP客户端可以是命令行工具如`ftp`或图形界面工具如FileZilla。配置主要包括设置服务器地址、端口、用户名和密码。连接成功后,可以测试上传、下载文件,创建、删除目录等操作,以验证FTP服务器配置是否正确。 四、...

    FTP上传下载,批量上传下载

    为了实现FTP上传和下载,你需要一个FTP客户端,它可以是命令行工具如`ftp`,也可以是图形用户界面的软件如FileZilla。FTP客户端需要知道服务器的地址(IP或域名)、端口号(默认为21)、用户名和密码。配置完成后,...

    Linux下安装配置ftp服务器

    在Linux系统中,FTP(File ...至此,你已经在Linux上成功安装并配置了FTP服务器,本地用户现在可以使用FTP客户端连接到服务器并进行文件传输。记得定期更新和审查你的VSFTPD配置,以保持服务器的安全性和最佳性能。

    java实现ftp自动上传文件

    3. Apache Commons Net:这是一个Apache软件基金会提供的Java库,包含了许多网络通信相关的工具,其中包括FTP客户端组件。这个库提供了一个`FTPClient`类,用于处理FTP连接、登录、文件传输等操作。 4. FTPClient...

Global site tag (gtag.js) - Google Analytics