Java实现ftp文件上传工具类及踩过的坑

一、环境
jdk1.8 + springboot2.3.2.RELEASE + commons-net-3.6.jar + commons-lang3-3.8.jar + commons-io-2.6.jar
二、添加pom.xml文件依赖

<dependency>
	<groupId>commons-net</groupId>
	<artifactId>commons-net</artifactId>
	<version>3.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.8</version>
</dependency>

<!-- 引入 Apache commons-io 包,方便操作文件-->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.6</version>
</dependency>

三、FTP 工具类

package org.lhj.pro.util;

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.PrintCommandListener;
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 java.io.*;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FtpUtil {
	private final static Log logger = LogFactory.getLog(FtpUtil.class);
	private static String LOCAL_CHARSET = "UTF-8";
	// FTP协议里面,规定文件名编码为iso-8859-1
	private static String SERVER_CHARSET = "ISO-8859-1";
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static Date TODAY_TIME = new Date();

	/**
	 * 
	 * @Description: 创建ftp客户端
	 * @return FTPClient 
	 * @Date: 2020年11月7日  上午9:31:02
	 * @Author: army
	 */
	public static FTPClient getFTPClient(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) {
		FTPClient ftpClient = new FTPClient();
		try {
			ftpClient = new FTPClient();
			ftpClient.connect(ftpHost, ftpPort); // 连接FTP服务器
			ftpClient.login(ftpUserName, ftpPassword); // 登陆FTP服务器
			ftpClient.setControlEncoding("UTF-8"); // 中文支持
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.enterLocalPassiveMode();
			if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
				logger.info("未连接到FTP,用户名或密码错误。");
				ftpClient.disconnect();
			} else {
				logger.info("FTP连接成功。");
			}
		} catch (SocketException e) {
			e.printStackTrace();
			logger.info("FTP的IP地址可能错误,请正确配置。");
		} catch (IOException e) {
			e.printStackTrace();
			logger.info("FTP的端口错误,请正确配置。");
		}
		return ftpClient;
	}

	// 判断ftp的目标文件下是否有此文件
	public static boolean isExsits(String ftpPath, String fileName, FTPClient ftpx) {

		try {
			FTPFile[] files = ftpx.listFiles(ftpPath);
			if (files != null && files.length > 0) {
				System.out.println("files size:" + files[0].getSize());
				for (FTPFile file : files) {
					String st = new String(file.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET);
					String st1 = new String(st.getBytes(SERVER_CHARSET), LOCAL_CHARSET);
					if (st1.equals(fileName)) {
						return true;
					}
				}

				return false;
			} else {
				return false;
			}
		} catch (Exception e) {
			logger.error("获取文件列表失败" + e.getMessage() + e.getClass().getName());
			return false;
			// e.printStackTrace();
		}
	}

	/**
	 * 从FTP服务器下载文件
	 * 
	 * @param ftpHost        FTP IP地址
	 * @param ftpUserName    FTP 用户名
	 * @param ftpPassword    FTP用户名密码
	 * @param ftpPort        FTP端口
	 * @param ftpPath        FTP服务器中文件所在路径 格式: ftptest/aa
	 * @param localPath      下载到本地的位置 格式:H:/download
	 * @param fileName       FTP服务器上要下载的文件名称
	 * @param targetFileName 本地上要的文件名称
	 */
	public static String downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
			String ftpPath, String localPath, String fileName, String targetFileName) {

		FTPClient ftpClient = null;
		try {
			ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);

			if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
				LOCAL_CHARSET = "UTF-8";
			}
			if (!ftpClient.changeWorkingDirectory(ftpPath)) {
				logger.error("文件夹路径不对");
				return "文件夹路径不对";
			}
			;
			boolean flag = isExsits(ftpPath, fileName, ftpClient);

			if (!flag) {
				logger.error("文件:" + fileName + " 不存在");
				return "文件:" + fileName + " 不存在";
			}

			String f_ame = new String(fileName.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING); // 编码文件格式,解决中文文件名

			File localFile = new File(localPath + File.separatorChar + targetFileName);
			OutputStream os = new FileOutputStream(localFile);
			ftpClient.retrieveFile(f_ame, os);
			os.close();
			ftpClient.logout();

			File file = new File(System.getProperty("java.io.tmpdir") + targetFileName);
			FileInputStream inputFile = new FileInputStream(file);
			byte[] buffer = new byte[(int) file.length()];
			inputFile.read(buffer);
			inputFile.close();

			if (file.exists()) {
				file.delete();// 删除文件
			}

			return "下载成功";
		} catch (FileNotFoundException e) {
			logger.error("没有找到" + ftpPath + "文件");
			e.printStackTrace();
		} catch (SocketException e) {
			logger.error("连接FTP失败.");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("文件读取错误。");
			e.printStackTrace();
		}
		return "下载失败";
	}
	
	/**
	 * 
	 * @Description: ftp上传
	 * @return String 
	 * @Date: 2020年11月7日  上午9:30:20
	 * @Author: army
	 */
	public static String uploadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, InputStream is,
			String name) {

		String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
		String path_wl = today;
		System.err.println(name);
		FTPClient ftp = new FTPClient();
		try {
			// 设置编码
			// ftp.setControlEncoding("utf-8");
			ftp.setControlEncoding("GBK");
			ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
			// 连接ftp服务器

			ftp.connect(ftpHost, ftpPort);
			// 响应码
			if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
				ftp.disconnect();
			}
			// 登录ftp
			boolean login = ftp.login(ftpUserName, ftpPassword);
			if (!login) {
				return "ftp服务器登录失败。请重新开始";
			}
			// 设置为二进制格式
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			ftp.enterLocalPassiveMode();
			// System.out.println("已连接"+ftp.isConnected());//查看ftp是否已连接
			logger.debug("ftp连接状态" + ftp.isConnected());

			if (!ftp.changeWorkingDirectory(path_wl)) {
				boolean b = ftp.makeDirectory(path_wl);
				if (b) {
					ftp.changeWorkingDirectory(path_wl);
					ftp.appendFile(name, is);
				}
			} else {
				ftp.appendFile(name, is);

			}

			logger.debug("写入成功==========");
		} catch (IOException e) {
			logger.error("文件保存失败:" + e.getMessage());
			e.printStackTrace();
			return "文件保存失败";
		} finally {
			try {

				ftp.logout();
				ftp.disconnect();
				if (ftp.isConnected()) {
					ftp.disconnect();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return "文件保存成功";

	}

}

四、定义FTP连接参数

package org.lhj.pro.constants;

public class FtpConstants {

    public static final String HOST = "127.0.0.1";
    public static final int PORT = 21;
    public static final String USER_NAME = "army";
    public static final String PASSWORD = "army";
}

五、创建Controller测试

package org.lhj.pro.controller;

import org.lhj.pro.constants.FtpConstants;
import org.lhj.pro.util.FtpUtil;
import org.lhj.pro.util.OssFileUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@RestController
@RequestMapping("/ftp)
public class TestController {

    @RequestMapping("/upload/localfile")
    public String localfile() {
        try {

            String filePath = "E:\\temp\\8721.jpg";
            File file = new File(filePath);
            FileInputStream fileInputStream = new FileInputStream(filePath);
            String fileName = file.getName();
            FtpUtil.getFTPClient(FtpConstants.HOST, FtpConstants.USER_NAME, FtpConstants.PASSWORD, FtpConstants.PORT);
            return FtpUtil.uploadFile(FtpConstants.HOST, FtpConstants.USER_NAME, FtpConstants.PASSWORD, FtpConstants.PORT,fileInputStream ,fileName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

六、浏览器查看上传结果
在这里插入图片描述

业务实现踩过的坑:

  1. 记得关闭防火墙
  2. 创建ftp时一定记得勾选写入权限
  3. Internet属性>>高级>>将“使用被动FTP(用于防火墙和DSL调制解调器的兼容)”选项去掉
    在这里插入图片描述
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值