目录
- 区别
- FtpUtil
- SFTPUtil
- 问题
区别
FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。FTP客户端通过FTP协议在服务器上下载资源。而一般要使用FTP需要在服务器上安装FTP服务。
而SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全,但是传输的效率比FTP要低,传输速度更慢(不过现实使用当中,没有发现多大差别)。SFTP和SSH使用的是相同的22端口,因此免安装直接可以使用。
总结:
一;FTP要安装,SFTP不要安装。
二;SFTP更安全,但更安全带来副作用就是的效率比FTP要低。
FtpUtil
<!--ftp文件上传-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>.6</version>
</dependency>
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.slfj.Logger;
import org.slfj.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.*;
@Component
public class FtpUtil {
private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);
//ftp服务器地址
@Value("${ftp.server}")
private String hostname;
//ftp服务器端口
@Value("${ftp.port}")
private int port;
//ftp登录账号
@Value("${ftp.userName}")
private String username;
//ftp登录密码
@Value("${ftp.userPassword}")
private String password;
/**
* 初始化FTP服务器
*
* @return
*/
public FTPClient getFtpClient() {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-");
try {
//设置连接超时时间
ftpClient.setDataTimeout( * 120);
logger.info("连接FTP服务器中:" + hostname + ":" + port);
//连接ftp服务器
ftpClient.connect(hostname, port);
//登录ftp服务器
ftpClient.login(username, password);
// 是否成功登录服务器
int replyCode = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(replyCode)) {
logger.info("连接FTP服务器成功:" + hostname + ":" + port);
} else {
logger.error("连接FTP服务器失败:" + hostname + ":" + port);
closeFtpClient(ftpClient);
}
} catch (IOException e) {
logger.error("连接ftp服务器异常", e);
}
return ftpClient;
}
/**
* 上传文件
*
* @param pathName 路径
* @param fileName 文件名
* @param inputStream 输入文件流
* @return
*/
public boolean uploadFileToFtp(String pathName, String fileName, InputStream inputStream) {
boolean isSuccess = false;
FTPClient ftpClient = getFtpClient();
try {
if (ftpClient.isConnected()) {
logger.info("开始上传文件到FTP,文件名称:" + fileName);
//设置上传文件类型为二进制,否则将无法打开文件
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//路径切换,如果目录不存在创建目录
if (!ftpClient.changeWorkingDirectory(pathName)) {
boolean flag = this.changeAndMakeWorkingDir(ftpClient, pathName);
if (!flag) {
logger.error("路径切换(创建目录)失败");
return false;
}
}
//设置被动模式,文件传输端口设置(如上传文件夹成功,不能上传文件,注释这行,否则报错refused:connect)
ftpClient.enterLocalPassiveMode();
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
isSuccess = true;
logger.info(fileName + "文件上传到FTP成功");
} else {
logger.error("FTP连接建立失败");
}
} catch (Exception e) {
logger.error(fileName + "文件上传异常", e);
} finally {
closeFtpClient(ftpClient);
closeStream(inputStream);
}
return isSuccess;
}
/**
* 删除文件
*
* @param pathName 路径
* @param fileName 文件名
* @return
*/
public boolean deleteFile(String pathName, String fileName) {
boolean flag = false;
FTPClient ftpClient = getFtpClient();
try {
logger.info("开始删除文件");
if (ftpClient.isConnected()) {
//路径切换
ftpClient.changeWorkingDirectory(pathName);
ftpClient.enterLocalPassiveMode();
ftpClient.dele(fileName);
ftpClient.logout();
flag = true;
logger.info("删除文件成功");
} else {
logger.info("删除文件失败");
}
} catch (Exception e) {
logger.error(fileName + "文件删除异常", e);
} finally {
closeFtpClient(ftpClient);
}
return flag;
}
/**
* 关闭FTP连接
*
* @param ftpClient
*/
public void closeFtpClient(FTPClient ftpClient) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
logger.error("关闭FTP连接异常", e);
}
}
}
/**
* 关闭文件流
*
* @param closeable
*/
public void closeStream(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException e) {
logger.error("关闭文件流异常", e);
}
}
}
/**
* 路径切换(没有则创建)
*
* @param ftpClient FTP服务器
* @param path 路径
*/
public void changeAndMakeWorkingDir(FTPClient ftpClient, String path) {
boolean flag = false;
try {
String[] path_array = path.split("/");
for (String s : path_array) {
boolean b = ftpClient.changeWorkingDirectory(s);
if (!b) {
ftpClient.makeDirectory(s);
ftpClient.changeWorkingDirectory(s);
}
}
flag = true;
} catch (IOException e) {
logger.error("路径切换异常", e);
}
return flag;
}
/**
* 从FTP下载到本地文件夹
*
* @param ftpClient FTP服务器
* @param pathName 路径
* @param targetFileName 文件名
* @param localPath 本地路径
* @return
*/
public boolean downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {
boolean flag = false;
OutputStream os = null;
try {
System.out.println("开始下载文件");
//切换FTP目录
ftpClient.changeWorkingDirectory(pathName);
ftpClient.enterLocalPassiveMode();
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
String ftpFileName = file.getName();
if (targetFileName.equalsIgnoreCase(ftpFileName)) {
File localFile = new File(localPath + targetFileName);
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
logger.info("下载文件成功");
} catch (Exception e) {
logger.error("下载文件失败", e);
} finally {
closeFtpClient(ftpClient);
closeStream(os);
}
return flag;
}
}
SFTPUtil
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>.1.54</version>
</dependency>
import com.jcraft.jsch.*;
import org.slfj.Logger;
import org.slfj.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;
@Component
public class SFTPUtil {
private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
private Session session = null;
private ChannelSftp channel = null;
private int timeout =;
/**
* 连接sftp服务器
*/
public boolean connect(String ftpUsername, String ftpAddress, int ftpPort, String ftpPassword) {
boolean isSuccess = false;
if (channel != null) {
System.out.println("通道不为空");
return false;
}
//创建JSch对象
JSch jSch = new JSch();
try {
// 根据用户名,主机ip和端口获取一个Session对象
session = jSch.getSession(ftpUsername, ftpAddress, ftpPort);
//设置密码
session.setPassword(ftpPassword);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
//为Session对象设置properties
session.setConfig(config);
//设置超时
session.setTimeout(timeout);
//通过Session建立连接
session.connect();
System.out.println("Session连接成功");
// 打开SFTP通道
channel = (ChannelSftp) session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
System.out.println("通道连接成功");
isSuccess = true;
} catch (JSchException e) {
logger.error("连接服务器异常", e);
}
return isSuccess;
}
/**
* 关闭连接
*/
public void close() {
//操作完毕后,关闭通道并退出本次会话
if (channel != null && channel.isConnected()) {
channel.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
}
/**
* 文件上传
* 采用默认的传输模式:OVERWRITE
* @param src 输入流
* @param dst 上传路径
* @param fileName 上传文件名
*
* @throws SftpException
*/
public boolean upLoadFile(InputStream src, String dst, String fileName) throws SftpException {
boolean isSuccess = false;
try {
if(createDir(dst)) {
channel.put(src, fileName);
isSuccess = true;
}
} catch (SftpException e) {
logger.error(fileName + "文件上传异常", e);
}
return isSuccess;
}
/**
* 创建一个文件目录
*
* @param createpath 路径
* @return
*/
public boolean createDir(String createpath) {
boolean isSuccess = false;
try {
if (isDirExist(createpath)) {
channel.cd(createpath);
return true;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
channel.cd(filePath.toString());
} else {
// 建立目录
channel.mkdir(filePath.toString());
// 进入并设置为当前目录
channel.cd(filePath.toString());
}
}
channel.cd(createpath);
isSuccess = true;
} catch (SftpException e) {
logger.error("目录创建异常!", e);
}
return isSuccess;
}
/**
* 判断目录是否存在
* @param directory 路径
* @return
*/
public boolean isDirExist(String directory) {
boolean isSuccess = false;
try {
SftpATTRS sftpATTRS = channel.lstat(directory);
isSuccess = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isSuccess = false;
}
}
return isSuccess;
}
/**
* 重命名指定文件或目录
*
*/
public boolean rename(String oldPath, String newPath) {
boolean isSuccess = false;
try {
channel.rename(oldPath, newPath);
isSuccess = true;
} catch (SftpException e) {
logger.error("重命名指定文件或目录异常", e);
}
return isSuccess;
}
/**
* 列出指定目录下的所有文件和子目录。
*/
public Vector ls(String path) {
try {
Vector vector = channel.ls(path);
return vector;
} catch (SftpException e) {
logger.error("列出指定目录下的所有文件和子目录。", e);
}
return null;
}
/**
* 删除文件
*
* @param directory linux服务器文件地址
* @param deleteFile 文件名称
*/
public boolean deleteFile(String directory, String deleteFile) {
boolean isSuccess = false;
try {
channel.cd(directory);
channel.rm(deleteFile);
isSuccess = true;
} catch (SftpException e) {
logger.error("删除文件失败", e);
}
return isSuccess;
}
/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 下载到本地路径
*/
public boolean download(String directory, String downloadFile, String saveFile) {
boolean isSuccess = false;
try {
channel.cd(directory);
File file = new File(saveFile);
channel.get(downloadFile, new FileOutputStream(file));
isSuccess = true;
} catch (SftpException e) {
logger.error("下载文件失败", e);
} catch (FileNotFoundException e) {
logger.error("下载文件失败", e);
}
return isSuccess;
}
}
问题
文件超出默认大小
#单文件上传最大大小,默认1Mb
spring.http.multipart.maxFileSize=100Mb
#多文件上传时最大大小,默认10Mb
spring.http.multipart.maxRequestSize=500MB