目录
- 区别
- 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.*; | |
public class FtpUtil { | |
private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class); | |
//ftp服务器地址 | |
"${ftp.server}") | (|
private String hostname; | |
//ftp服务器端口 | |
"${ftp.port}") | (|
private int port; | |
//ftp登录账号 | |
"${ftp.userName}") | (|
private String username; | |
//ftp登录密码 | |
"${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; | |
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