前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA 实现 FTP 文件上传、下载和删除

JAVA 实现 FTP 文件上传、下载和删除

作者头像
AI码真香
发布2022-09-13 17:44:40
1.6K0
发布2022-09-13 17:44:40
举报
文章被收录于专栏:AI码真香
一、背景

项目中可能经常会遇到需要文件上传到服务器上,需要的时候从服务器获取。结合之前的博客 阿里云服务器上搭载 FTP 站点 本篇博客记录:如何通过java 实现FTP文件上传下载和删除功能。虽然网上有很多教程,但是或多或少都会有些问题。看到本篇文章,也许会让你少踩坑哦~

二、开发环境
  • IDEA 2017.3.5
  • Maven 3.5
  • JDK 1.8
三、步骤详情
3.1、通过Apache FTP工具类实现文件上传下载以及删除

pom.xml 文件中,添加对应依赖:

代码语言:javascript
复制
<dependency>
  <groupId>commons-net</groupId>
  <artifactId>commons-net</artifactId>
  <version>3.3</version>
</dependency>

代码中使用到单元测试,需添加依赖:

代码语言:javascript
复制
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
</dependency>
3.2、直接上代码

创建一个 FtpUtil 类:

代码语言:javascript
复制
package com.xmlvhy.ftp;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.junit.Assert;
import org.junit.Test;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Author: 小莫
 * Date: 2019-03-15 10:53
 * Description: ftp 文件上传下载删除工具类
 */
public class FtpUtil {

    /**
     * Description: 向FTP服务器上传文件
     *
     * @param url      FTP服务器hostname
     * @param port     FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param path     FTP服务器保存目录
     * @param filename 上传到FTP服务器上的文件名
     * @param input    输入流
     * @return 成功返回true,否则返回false
     */
    public static Map<String, Object> uploadFile(String url, int port, String username, String password, String path, String filename, FileInputStream input) {
        boolean success = false;
        Map<String, Object> map = new HashMap<>();
        String filepath = "";
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(url, port);//连接FTP服务器
            //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            reply = ftp.getReplyCode();

            //判断reply的code是否正常,一般正常为2开头的code
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                map.put("status", success);
                map.put("filepath", filepath);
                return map;
            }

            boolean a = ftp.changeWorkingDirectory("/");
            System.out.println("转换目录结果1:" + a);

            String basePath = "/";
            path = "static/images/20190315";
            if (path == null || path.equals("/")) {//如果输入的路径为空或者为根路径,则不转换操作目录

            } else {//否则创建想要上传文件的目录,并且将操作目录转为新创建的目录

                //如果目录不存在创建目录
                String[] dirs = path.split("/");
                String tempPath = basePath;
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            success = false;
                        } else {
                            boolean b = ftp.changeWorkingDirectory(tempPath);
                            System.out.println("转换目录结果2:" + b);
                        }
                    }
                }

                //ftp.makeDirectory(path);
                //boolean b = ftp.changeWorkingDirectory(path);
                //System.out.println("转换目录结果2:"+b);
            }

            //ftp上传文件是以文本形式传输的,所以多媒体文件会失真,需要转为二进制形式传输
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            //转码后可以文件名可以为中文
            ftp.storeFile(new String(filename.getBytes("GBK"), "iso-8859-1"), input);
            input.close();
            ftp.logout();
            success = true;
            filepath = "ftp://" + url + ":" + port + "/" + path + "/" + filename;
            map.put("status", success);
            map.put("filepath", filepath);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (Exception ioe) {

                }
            }
        }
        return map;
    }

    /**
     * Description: 从FTP服务器下载文件
     *
     * @param host       FTP服务器hostname
     * @param port       FTP服务器端口
     * @param username   FTP登录账号
     * @param password   FTP登录密码
     * @param remotePath FTP服务器上的相对路径
     * @param fileName   要下载的文件名
     * @param localPath  下载后保存到本地的路径
     * @return
     */
    public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
                                       String fileName, String localPath) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return result;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    File localFile = new File(localPath + "/" + ff.getName());

                    OutputStream is = new FileOutputStream(localFile);
                    ftp.retrieveFile(ff.getName(), is);
                    is.close();
                }
            }

            ftp.logout();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

    /**
     * Description: 从FTP服务器删除文件
     *
     * @param host       FTP服务器hostname
     * @param port       FTP服务器端口
     * @param username   FTP登录账号
     * @param password   FTP登录密码
     * @param remotePath FTP服务器上的相对路径
     * @param fileName   要删除的文件名
     * @return
     */
    public static boolean deleteFile(String host, int port, String username, String password, String remotePath,
                                     String fileName) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(host, port);
            // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(username, password);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return result;
            }
            ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    ftp.deleteFile(fileName);
                }
            }
            //退出登录
            ftp.logout();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }
}

再创建一个FtpTest 类,对 FtpUtil 中的方法进行测试

代码语言:javascript
复制
package com.xmlvhy.ftp;

import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * Author: 小莫
 * Date: 2019-03-18 15:24
 * Description: ftp 工具类测试
 */
public class TtpTest {

    /**
     *功能描述: 上传文件
     * @Author 小莫
     * @Date 15:26 2019/03/18
     * @Param []
     * @return void
     */
    @Test
    public void test1() {
        try {
            FileInputStream in = new FileInputStream(new File("F:/user.png"));
            String filePath = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String fileName = "user.png";
            Map<String, Object> map = FtpUtil.uploadFile("您的服务器域名", 21, "ftptest", "ftp账户密码", filePath, fileName, in);
            System.out.println(map.get("status") + "====>" + map.get("filepath"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     *功能描述: 下载文件
     * @Author 小莫
     * @Date 15:26 2019/03/18
     * @Param []
     * @return void
     */
    @Test
    public void test2() {
        boolean flag = FtpUtil.downloadFile("您的服务器域名", 21, "ftptest", "ftp账户密码", "/", "user.png", "E:/");
        Assert.assertEquals(true, flag);
    }


    /**
     *功能描述: 删除文件
     * @Author 小莫
     * @Date 15:26 2019/03/18
     * @Param []
     * @return void
     */
    @Test
    public void test3() {
        boolean flag = FtpUtil.deleteFile("您的服务器域名", 21, "ftptest", "ftp账户密码", "static/images/20190315", "user.png");
        Assert.assertEquals(true, flag);
    }
}

测试类中参数的相关说明

  • 文件上传测试模块:我是本地 F 盘中有 ‘user.png’ 文件,这里注意修改您的路径文件;
  • 特别注意:ftp 登录进去默认是到您 ftp 服务器的根路径,这里 ftp服务器的根路径以及 remotePath 都是 "/" ,这个路径一定要对,要不然多层级目录上传文件时候, makeDirectory(...)这个方法一直返回false,上传失败,我也是卡在这。当时还各种怀疑 ftp 服务器的配置啊,目录权限啊是不是有问题,卡了蛮久~

备注:

  • changeWorkingDirectory()方法,是用来切换目录的,如果切换目录成功则返回 true,反之返回 false
  • makeDirectory() 方法,是用来创建目录,该方法注意:只能创建一次目录(如果有多层目录的,则需要通过一层一层的去创建);如果当前存在目录则返回 true,反之如果创建失败则返回 false ;
代码语言:javascript
复制
			//ftp站点的根目录,也就是你ftp账户登录成功进入到的目录
			String basePath = "/";
			//文件所要上传的路径,这个目录根据自己设定
            path = "static/images/20190315";
            if (path == null || path.equals("/")) {//如果输入的路径为空或者为根路径,则不转换操作目录

            } else {//否则创建想要上传文件的目录,并且将操作目录转为新创建的目录
                //如果目录不存在创建目录
                String[] dirs = path.split("/");
                String tempPath = basePath;
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            success = false;
                        } else {
                            boolean b = ftp.changeWorkingDirectory(tempPath);
                            System.out.println("转换目录结果2:" + b);
                        }
                    }
                }
            }
四、测试结果
4.1、运行 test1() 方法上传一个文件

可以看到,文件成功上传到设定的目录中去了。删除 和 下载功能类似,只是调用的方法不一样,这里便不再展示结果了~

本篇博客涉及的代码 获取源码

本文作者: AI码真香

本文标题: JAVA 实现 FTP 文件上传、下载和删除

本文网址: https://www.xmlvhy.com/article/67.html

版权说明: 自由转载-非商用-非衍生-保持署名 署名-非商业性使用4.0 国际 (CC BY-NC 4.0)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景
  • 二、开发环境
  • 三、步骤详情
    • 3.1、通过Apache FTP工具类实现文件上传下载以及删除
      • 3.2、直接上代码
      • 四、测试结果
        • 4.1、运行 test1() 方法上传一个文件
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档