最近项目上需要使用ftp服务器和第三方进行资源交互,于是写了个小demo记录下~

基础知识

FTP服务器

多级目录下创建文件

一直以为ftp服务器多级目录创建和java中目录创建一样,然而并不是滴~ 可参考文档:关于ftp上传changeWorkingDirectory()方法的路径切换问题
将文件hello.json上传至/home/upload/目录下步骤:

  1. 先使用FTPClient.changeWorkingDirectory("home"),判断home目录是否存在?若不存在则2
  2. 使用FTPClient.makeDirectory("home") 创建目录,同时使用FTPClient.changeWorkingDirectory("home")将ftp session指向home目录
  3. 使用FTPClient.changeWorkingDirectory("upload")判断upload目录是否存在?若不存在则4
  4. 使用FTPClient.makeDirectory("upload")创建目录,同时使用FTPClient.changeWorkingDirectory("upload")将ftp session指向upload目录
  5. 使用FTPClient.storeFile(fileName, is); 上传文件流is

springboot FTP服务器 上传&&下载示例demo-LMLPHP

实践出真知

引入依赖和加入配置

  1. pom.xml 中添加依赖
<dependency>
	<groupId>commons-net</groupId>
	<artifactId>commons-net</artifactId>
	<version>3.6</version>
</dependency>
  1. 在application.yml中添加ftp服务器配置(多环境则需要在application-dev/test/prod.yml中分别配置)
ftp:
  hostname: 172.16.1.1
  port: 21
  username: lizzy
  password: lizzy
  root-path: /upload/

定义配置bean

package com.lizzy.common.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Data;

@ConfigurationProperties(prefix = "ftp")
@Data
@Component
public class FtpConfig {

	private String hostname;

	private Integer port;

	private String username;

	private String password;

	private String rootPath;

}

定义FTP工具类

上传

package com.lizzy.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.util.StringUtils;

import com.ankon.common.config.FtpConfig;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@UtilityClass
@Slf4j
public class FTPUtil {

	/**
	 * 上传文件至FTP服务器
	 * @param config ftp服务器配置
	 * @param path 文件子路径
	 * @param fileName 文件名
	 * @param is 文件流
	 */
	public static void upload(FtpConfig config, String path, String fileName, InputStream is) {

		FTPClient client = new FTPClient();
		client.enterLocalPassiveMode();
		try {
			// 连接服务器
			client.connect(config.getHostname(), config.getPort());
			// 登录
			client.login(config.getUsername(), config.getPassword());
			int reply = client.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {

				// 连接失败 
				client.disconnect();
				log.info("FTP服务器配置链接失败!请检查配置:{}", config.toString());
				return ;
			}

			// 切换到上传目录
			final String filePath = config.getRootPath() + path;
			if (!client.changeWorkingDirectory(filePath)) {
				// 目录不存在则创建
				String[] dirs = filePath.split("/");
				for (String dir : dirs) {

					if (StringUtils.isEmpty(dir)) {
						continue ;
					}
					if (!client.changeWorkingDirectory(dir)) {
						client.makeDirectory(dir);
						client.changeWorkingDirectory(dir);
					}
				}
			}

			//设置上传文件的类型为二进制类型
			client.setFileType(FTP.BINARY_FILE_TYPE);
			client.storeFile(fileName, is);
			log.debug("文件{}成功上传至FTP服务器!", filePath + "/" + fileName);
			client.logout();

		} catch (IOException e) {
			log.info("FTP服务器配置链接失败!错误:{}", e.getMessage());
			e.printStackTrace();
		} finally {
			try {
				is.close();
				if (client.isConnected()) {
					client.disconnect();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}

下载

package com.lizzy.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.util.StringUtils;

import com.ankon.common.config.FtpConfig;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@UtilityClass
@Slf4j
public class FTPUtil {

	/**
	 * 从FTP服务器下载文件流
	 * @param config FTP服务器配置
	 * @param path 相对目录(不包含根目录)
	 * @param fileName 文件名
	 * @return
	 */
	public static InputStream download(FtpConfig config, String path, String fileName) {

		FTPClient client = new FTPClient();
		client.enterLocalPassiveMode();
		try {
			// 连接服务器
			client.connect(config.getHostname(), config.getPort());
			// 登录
			client.login(config.getUsername(), config.getPassword());
			int reply = client.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {

				// 连接失败 
				client.disconnect();
				log.info("FTP服务器配置链接失败!请检查配置:{}", config.toString());
				return null;
			}

			// 切换到下载目录
			final String filePath = config.getRootPath() + path;
			client.changeWorkingDirectory(filePath);
			//设置上传文件的类型为二进制类型
			client.setFileType(FTP.BINARY_FILE_TYPE);
			InputStream is = client.retrieveFileStream(fileName);
			log.debug("从FTP服务器下载文件({})成功!", fileName);
			return is;

		} catch (IOException e) {
			log.info("FTP服务器配置链接失败!错误:{}", e.getMessage());
			e.printStackTrace();
		} finally {

			try {
				client.logout();
				if (client.isConnected()) {
					client.disconnect();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

遇到的问题

文件覆盖

FTP服务器上同名文件是否覆盖的配置

后记

demo写的很匆忙,后续遇到问题了再更新~

09-15 12:46