使用ftp进行文件上传,含客户端和服务端实现

大家好,欢迎关注我的公众号“星记事”,更多技术分享与讲解


什么是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目录下。


大家好,欢迎关注我的公众号“星记事”,技术分享与讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值