大家好,欢迎关注我的公众号“星记事”,更多技术分享与讲解
什么是FTP协议?
FTP(File Transfer Protocol,文件传输协议)是一种基于TCP/IP网络的应用层协议,专门设计用于在互联网上实现可靠、高效地传输文件。FTP协议定义了客户端(用户端)和服务器端之间进行文件交互的标准规则和格式,使得用户能够通过网络便捷地上传、下载、管理和共享文件。
现代FTP使用通常推荐使用安全的变种,如FTPS(FTP over SSL/TLS)或SFTP(SSH File Transfer Protocol),以加密数据传输过程,保护敏感信息免受窃听和中间人攻击。尽管如此,传统的未加密FTP仍然在某些场景下被使用,尤其是在内部网络或对安全性要求不高的环境中。
使用ftp协议上传文件
Java使用FTP协议上传文件,需要一个FTP客户端和一个FTP服务器端。下面分别介绍客户端和服务端的实现。
FTP客户端
可以使用Apache Commons Net库提供的FTPClient类来实现Java FTP客户端。首先需要添加该库的依赖:
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
接下来,可以使用以下代码实现FTP文件上传:
package com.freelance.client.radiologyUploadToolNew;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.FileInputStream;
import java.io.IOException;
public class FtpClientUpload {
public static String serverIp = "192.168.0.0"; // 替换为实际服务器IP
public static int serverPort = 21; // 或者服务器使用的非默认端口
public static String username = "DR";
public static String password = "test";
public static String localFilePath = "D:\\temp\\2024\\04\\02\\1.2.276.0.7230010.3.1.4.3335301770.5396.1711433246.460(1).jpg"; // 要上传的本地文件路径
public static String remoteDirectory = "/test"; // FTP服务器上的目标目录
/** 本地字符编码 */
private static String LOCAL_CHARSET = "GBK";
// FTP协议里面,规定文件名编码为iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1";
public static void main(String[] args) throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(serverIp, serverPort);
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
throw new RuntimeException("Failed to connect to FTP server.");
}
boolean loginSuccess = ftpClient.login(username, null);
if (!loginSuccess) {
throw new RuntimeException("Failed to login to FTP server.");
}
// 设置传输模式为二进制(对于非文本文件)
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 更改为目标远程目录(如果不存在,可能需要在服务器端预先创建)
if (!ftpClient.changeWorkingDirectory(remoteDirectory)){
createRemoteDirectory(ftpClient, remoteDirectory);
// 再次尝试切换到新创建的目录
if (!ftpClient.changeWorkingDirectory(remoteDirectory)) {
throw new IOException("Failed to change to remote directory: " + remoteDirectory);
}
}
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 设置被动模式
// 上传文件
boolean uploadSuccess = ftpClient.storeFile(new String("1.2.276.0.7230010.3.1.4.3335301770.5396.1711433246.460(1).jpg".getBytes(LOCAL_CHARSET), SERVER_CHARSET), new FileInputStream(localFilePath));
if (!uploadSuccess) {
throw new RuntimeException("Failed to upload file to FTP server.");
}
System.out.println("File uploaded successfully.");
// 关闭FTP连接
ftpClient.logout();
ftpClient.disconnect();
}
private static void createRemoteDirectory(FTPClient ftpClient, String remoteDirectoryPath) throws IOException {
String[] dirs = remoteDirectoryPath.split("/");
for (int i = 0; i < dirs.length; i++) {
String dir = dirs[i];
if (dir.length() > 0) {
if (!ftpClient.changeWorkingDirectory(dir)) {
if (!ftpClient.makeDirectory(dir)) {
throw new IOException("Failed to create remote directory: " + dir);
}
ftpClient.changeWorkingDirectory(dir);
}
}
}
}
}
在上述代码中,需要替换serverIp、serverPort、username、password、localFilePath为实际的值。
FTP服务器端
可以使用Apache FTPServer库提供的FtpServerFactory和ListenerFactory类来实现Java FTP服务器端。首先需要添加该库的依赖:
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.1.0</version>
</dependency>
接下来,可以使用以下代码实现FTP服务器端:
package com.freelance.client.radiologyUploadToolNew;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import java.util.List;
public class JavaFtpServer {
public static void main(String[] args) {
JavaFtpServer.createFtp1();
// JavaFtpServer.createFtp2();
}
//创建匿名用户
public static void createFtp1(){
try {
FtpServerFactory serverFactory = new FtpServerFactory();
BaseUser user = new BaseUser();
user.setName(name);
// user.setPassword("test");
user.setHomeDirectory(homeDirectory);
List<Authority> authority = new ArrayList<Authority>();
authority.add(new WritePermission());
// //最大同时登录人数+最大同时登录ip
// authority.add(new ConcurrentLoginPermission(2,3));
// //最大下载速度+最大上传速度
// authority.add(new TransferRatePermission(10,30));
user.setAuthorities(authority);
BaseUser user2 = new BaseUser();
user2.setName("test2");
// user.setPassword("test");
user2.setHomeDirectory("D:\\temp2");
List<Authority> authority2 = new ArrayList<Authority>();
authority2.add(new WritePermission());
user2.setAuthorities(authority2);
serverFactory.getUserManager().save(user);
serverFactory.getUserManager().save(user2);
FtpServer server = serverFactory.createServer();
server.start();
System.out.println("ftp搭建完成");
}catch (FtpException e){
e.printStackTrace();
}
}
}
先将JavaFtpServer跑起来,然后再跑FtpClientUpload,就可以看到客户端需要上传的文件上传到了JavaFtpServer目录下。
大家好,欢迎关注我的公众号“星记事”,技术分享与讲解