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

文章目录

  • 基础知识
    • FTP服务器
    • 多级目录下创建文件
  • 实践出真知
    • 引入依赖和加入配置
    • 定义配置bean
    • 定义FTP工具类
      • 上传
      • 下载
  • 遇到的问题
    • 文件覆盖
  • 后记

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

基础知识

FTP服务器

FTP(File Transfer Protocol)即文件传输协议,是一种基于TCP的协议,采用客户/服务器模式。通过FTP协议,用户可以在FTP服务器中进行文件的上传或下载等操作。虽然现在通过HTTP协议下载的站点有很多,但是由于FTP协议可以很好地控制用户数量和宽带的分配,快速方便地上传、下载文件,因此FTP已成为网络中文件上传和下载的首选服务器。同时,它也是一个应用程序,用户可以通过它把自己的计算机与世界各地所有运行FTP协议的服务器相连,访问服务器上的大量程序和信息。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_第1张图片

实践出真知

引入依赖和加入配置

  1. pom.xml 中添加依赖
<dependency>
	<groupId>commons-netgroupId>
	<artifactId>commons-netartifactId>
	<version>3.6version>
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写的很匆忙,后续遇到问题了再更新~

你可能感兴趣的:(Java,springboot,服务器,spring,boot,java)