前言
网上百度了很多FTP的java 工具类,发现文章代码都比较久远,且代码臃肿,即使搜到了代码写的还可以的,封装的常用操作方法不全面,于是自己花了半天实现一个好用的工具类。最初想用java自带的FTPClient 的jar 去封装,后来和apache的jar工具包对比后,发现易用性远不如apache,于是决定采用apache的ftp的jar 封装ftp操作类。
工具类方法
- 账户密码登录方法
- 无账号密码登录方法
- 字符转码方法
- 判断文件目录是否存在方法
- 获取文件列表方法
- 上传文件方法
- 下载文件方法
- 上传文件夹方法
- 下载文件夹方法
- 删除文件方法
- 删除文件夹方法
- 创建文件夹方法
- 文件重命名方法
代码展示
pom文件引入依赖关系 commons-net jar
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
工具类完整代码
import org.apache.commons.net.ftp.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Java FTP工具类
*/
public class FTPUtil {
private static FTPClient ftp;
/**
* 方法描述: 转码
*/
private static String transcode(String text){
try {
return new String(text.getBytes("GBK"),FTP.DEFAULT_CONTROL_ENCODING);
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* 方法描述: 连接 ftp服务器 匿名登录无密码
*/
public static void connectServer(String ip, int port) throws IOException {
connectServer(ip,port,"anonymous",null);
}
/**
* 方法描述: 连接 ftp服务器
*/
public static void connectServer(String ip, int port, String user, String password) throws IOException {
// 连接ftp服务器
ftp = new FTPClient();
ftp.connect(ip, port);
// 登录ftp服务器
ftp.login(user, password);
//设置编码
ftp.setControlEncoding("GBK");
//设置文件类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
}
/**
* 关闭连接
*/
public static void closeServer() throws IOException {
if (ftp.isConnected()) {
ftp.logout();
ftp.disconnect();
}
}
/**
* 判断目录是否存在
*/
public static boolean existDirectory(String pathname) throws IOException {
boolean flag = false;
FTPFile[] ftpFileArr = ftp.listFiles(pathname);
for (FTPFile ftpFile : ftpFileArr) {
if (ftpFile.isDirectory() && ftpFile.getName().equalsIgnoreCase(pathname)) {
flag = true;
break;
}
}
return flag;
}
/*
* 获取文件列表
*/
public static List<String> listFiles(String path) throws IOException {
FTPFile[] ftpFiles = ftp.listFiles(path);
List<String> retList = new ArrayList<String>();
for (FTPFile ftpFile : ftpFiles) {
retList.add(ftpFile.getName());
}
return retList;
}
/**
* 上传文件
*/
public static boolean uploadFile(String remote,String local) throws IOException {
InputStream is=new FileInputStream(local);
return ftp.storeFile(transcode(remote),is);
}
/**
* 下载文件
*/
public static boolean downloadFile(String remote,String local) throws IOException {
OutputStream out=new FileOutputStream(local);
return ftp.retrieveFile(transcode(remote),out);
}
/**
* 删除文件
*/
public static boolean deleteFile(String remote) throws IOException {
return ftp.deleteFile(transcode(remote));
}
/**
* 删除文件夹
*/
public static void deleteFolder(String remote) throws IOException {
FTPFile[] ftpFiles=ftp.listFiles(transcode(remote));
for (FTPFile ftpFile : ftpFiles) {
if(ftpFile.isDirectory()){
deleteFolder(remote+"/"+ftpFile.getName());
ftp.removeDirectory(transcode(remote+"/"+ftpFile.getName()));
}else{
deleteFile(ftpFile.getName());
}
}
ftp.removeDirectory(transcode(remote));
}
/**
* 上传文件夹到ftp服务器
*/
public static void uploadFolder(String remote,String local) throws IOException {
File localFile=new File(local);
if(localFile.isDirectory()){
String remoteDir=remote+"/"+localFile.getName();
makeDirectory(remoteDir);
File[] partFiles=localFile.listFiles();
for (File file : partFiles) {
if(file.isDirectory()){
uploadFolder(remoteDir+"/"+file.getName(),local+"/"+file.getName());
}else {
uploadFile(remoteDir+"/"+file.getName(),local+"/"+file.getName());
}
}
}
}
/**
* 下载文件夹到本地
*/
public static void downloadFolder(String remote,String local) throws IOException {
File localFile=new File(local);
if(!localFile.exists()){
localFile.mkdirs();
}
FTPFile[] ftpFiles=ftp.listFiles(transcode(remote));
for (FTPFile ftpFile : ftpFiles) {
if(ftpFile.isDirectory()){
downloadFolder(remote+"/"+ftpFile.getName(),local+"/"+ftpFile.getName());
}else {
downloadFile(remote+"/"+ftpFile.getName(),local+"/"+ftpFile.getName());
}
}
}
/**
* 创建文件夹
*/
public static void makeDirectory(String remote) throws IOException {
if(remote.startsWith("/")){
remote=remote.substring(1);
}
String[] dirNames = remote.split("/");
String tempPath="";
for (String dirName : dirNames) {
tempPath=tempPath+"/"+dirName;
ftp.makeDirectory(transcode(tempPath));
}
}
/**
* 重命名
*/
public static boolean rename(String from, String to) throws IOException {
return ftp.rename(transcode(from),transcode(to));
}
}
使用示例
public static void main(String[] args) throws IOException {
//匿名免密码登录
FTPUtil.connectServer("172.16.10.201",19001,"anonymous",null);
//下载ftp根目录所有文件到本地文件夹
FTPUtil.downloadFolder("/","D://ftp");
//删除文件夹以及文件
FTPUtil.deleteFolder("tarzan");
//创建文件夹
FTPUtil.makeDirectory("tarzan/cms");
//文件夹或文件重命名
FTPUtil.rename("泰山","泰山123");
//上传文件夹
FTPUtil.uploadFolder("software","D:\\Git");
}
相关知识
FTP(File Transfer Protocol)是一种用于在计算机网络上进行文件传输的标准协议。它允许用户在客户端和服务器之间传输文件,包括上传、下载、删除和重命名等操作。在本文中,我们将详细介绍FTP协议的原理、工作方式以及常见的使用案例。
FTP协议原理
FTP协议是基于客户端-服务器模型的,通常使用TCP/IP协议进行通信。FTP客户端向FTP服务器发送命令来控制文件传输和管理操作。
在FTP协议中,客户端和服务器之间有两个TCP连接:控制连接和数据连接。控制连接负责传输命令和响应消息,而数据连接则用于实际的文件传输。
FTP工作方式
FTP工作方式有两种:主动模式(Active Mode)和被动模式(Passive Mode)。
在主动模式下,客户端在数据传输之前先打开一个临时端口,然后将该端口号告诉服务器。服务器从该端口向客户端发出数据连接请求,进行数据传输。
在被动模式下,服务器在传输数据之前打开一个临时端口,并将该端口号告诉客户端。客户端从该端口向服务器发出数据连接请求,进行数据传输。
FTP命令和响应
FTP协议定义了一系列命令和响应消息,用于控制文件传输和管理。常见的FTP命令包括:
- USER:用于指定用户名
- PASS:用于指定密码
- LIST:列出当前目录的文件和子目录
- RETR:从服务器下载文件
- STOR:向服务器上传文件
- DELE:删除服务器上的文件
- RENAME:重命名服务器上的文件
FTP服务器会根据接收到的命令返回相应的响应消息,以指示命令执行的结果。响应消息包含一个三位数的状态码,以及对应的文本说明。
FTP安全性
由于FTP协议最初设计时并未考虑安全性,因此在传输过程中数据是明文传输的,容易受到窃听和篡改的威胁。为了提高安全性,可以使用以下方法:
使用FTP over SSL/TLS(FTPS):在FTP协议的基础上添加了SSL/TLS安全层,使数据加密传输。
使用SSH File Transfer Protocol(SFTP):基于SSH协议的文件传输协议,提供了加密传输和身份验证功能。
使用案例
FTP协议广泛应用于各个领域,常见的使用案例包括:
- 网站维护:通过FTP将网站文件从本地上传到Web服务器上,以更新和发布网站内容。
- 文件备份:将重要文件和数据备份到远程FTP服务器上,提供灾难恢复能力。
- 软件升级:通过FTP下载软件的最新版本和补丁,并进行安装和升级。
- 大文件传输:当需要传输大容量的文件时,使用FTP可以更有效地完成传输。
总结
FTP是一种用于在计算机网络上进行文件传输的标准协议。它通过客户端-服务器模型,在控制连接和数据连接之间进行文件传输。FTP协议提供了一系列命令和响应消息,用于控制文件操作。为了提高安全性,可以使用FTPS或SFTP等安全扩展。FTP广泛应用于网站维护、文件备份、软件升级和大文件传输等场景。