java使用Sftp上传文件(图片、视频等)到Linux服务器上
jar包依赖
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<!-- Slf4j依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
上传下载工具类
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;
/**
* @Description 文件上传下载
*/
@Slf4j
public class UploadFileUtil {
private static Session session;
private static ChannelSftp channelSftp;
/**
* 获取sftp连接
* @param ftpaddress 地址
* @param ftpPassword 密码
* @param ftpUserName 用户名
*/
public static ChannelSftp getSFTPClient(String ftpaddress, String ftpPassword,
String ftpUserName,int ftpPort) {
//开始时间 用于计时
long startTime = System.currentTimeMillis();
// 创建JSch对象
JSch jsch = new JSch();
Channel channel = null;
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);
// 设置timeout时间
//session.setTimeout(timeout);
// 通过Session建立链接
session.connect();
// 打开SFTP通道
channel = session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
long endTime = System.currentTimeMillis();
log.info("连接sftp成功耗时" + (endTime - startTime) + "毫秒");
return (ChannelSftp) channel;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 判断目录是否存在
* @param directory
* @param sftp
* @return boolean
*/
public static boolean isDirExist(String directory, ChannelSftp sftp) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
log.info("目录"+directory+"已存在");
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
log.info("目录"+directory+"不存在");
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* 创建目录
* @param createpath
* @param sftp
*/
public static void createDir(String createpath, ChannelSftp sftp) {
try {
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(),sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
log.info("创建目录"+filePath.toString()+"成功");
// 进入并设置为当前目录
sftp.cd(filePath.toString());
log.info("进入目录"+filePath.toString());
}
}
sftp.cd(createpath);
} catch (SftpException e) {
// throw new SystemException("创建路径错误:" + createpath);
}
}
/**
* 关闭链接资源
*/
public static void close() {
if (channelSftp != null && channelSftp.isConnected()) {
channelSftp.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
log.info("关闭连接资源");
}
/**
* @Description //
* * @Param [host:上传主机IP, port:端口22, userName:登录名, password:密码
* * remoteFile:上传路径,in:输入流格式文件, pathName:文件名称]
* @param host 上传主机IP
* @param port 端口 默认22
* @param userName 登录名
* @param password 密码
* @param remoteFile 上传服务器路径
* @param in 输入流格式文件
* @param pathName 上传文件名称
* @return boolean
*/
public static boolean uploadFile(String host, int port, String userName, String password, String remoteFile, InputStream in, String pathName){
try{
//建立连接
if (channelSftp == null || !channelSftp.isConnected()) {
channelSftp=getSFTPClient(host,password,userName,port);
}
//判断文件夹是否存在,不存在则创建
if (isDirExist(remoteFile,channelSftp)) {
channelSftp.put(in, remoteFile + "/" +pathName);
log.info("文件上传成功,文件路径"+remoteFile + "/" +pathName);
close();
return true;
} else {
//创建文件夹再上传文件
createDir(remoteFile ,channelSftp);
channelSftp.put(in, remoteFile + "/" +pathName);
log.info("文件上传成功,文件路径"+remoteFile + "/" +pathName);
close();
return true;
}
}catch(Exception e){
e.printStackTrace();
close();
}
return false;
}
/**
* 文件夹上传
* @param host sftp地址
* @param port sftp端口
* @param userName 登录名
* @param password 密码
* @param file 上传的文件夹
* @param remoteFile sftp服务器文件存放路径
* @return true 成功,false 失败
*/
public static boolean uploadDstFile(String host, int port, String userName, String password,
MultipartFile[] file, String remoteFile){
boolean b = false;
//建立连接
if (channelSftp == null || !channelSftp.isConnected()) {
channelSftp=getSFTPClient(host,password,userName,port);
}
if (channelSftp.isConnected()) {
b = uploadFiles(file,remoteFile);//循环迭代文件夹
close();//关闭连接
}
return b;
}
/**
* 循环读取文件夹里面的文件上传,不支持文件夹里面嵌套文件夹上传
* @param file 文件
* @param remoteFile 服务器路径
* @return
*/
private static boolean uploadFiles(MultipartFile[] file, String remoteFile) {
try {
for (int i = 0; i < file.length; i++) {
InputStream in = null;
try {
in = file[i].getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
if (i == 0) {//获取设置文件夹名称
remoteFile = remoteFile + "/" + file[i].getOriginalFilename().substring(0, file[i].getOriginalFilename().lastIndexOf("/"));
}
//获取设置文件名称
String originalFilename = file[i].getOriginalFilename().substring(file[i].getOriginalFilename().lastIndexOf("/"));
//判断文件夹是否存在,存在则直接上传
if (isDirExist(remoteFile, channelSftp)) {
channelSftp.put(in, remoteFile + "/" + originalFilename);
log.info("文件上传成功,文件路径" + remoteFile + "/" + originalFilename);
} else {
//创建文件夹在上传文件
createDir(remoteFile, channelSftp);
channelSftp.put(in, remoteFile + "/" + originalFilename);
log.info("文件上传成功,文件路径" + remoteFile + "/" + originalFilename);
}
}
} catch (SftpException e) {
e.printStackTrace();
}
close();
return true;
}
/**
* @Description 下载服务器目录下的全部文件
* @param host 上传主机IP
* @param port 端口 默认22
* @param userName 登录名
* @param password 密码
* @param src 服务器文件目录
* @param localPath 本地存放地址
* @return boolean
*/
public static boolean downloadFiles(String host, int port, String userName, String password, String src, String localPath){
try{
//建立连接
if (channelSftp == null || !channelSftp.isConnected()) {
channelSftp=getSFTPClient(host,password,userName,port);
}
//获取文件目录下所有的文件
Vector vector = channelSftp.ls(src);
for (Object item : vector) {
if (item instanceof com.jcraft.jsch.ChannelSftp.LsEntry) {
String fileName = ((com.jcraft.jsch.ChannelSftp.LsEntry) item).getFilename();
if (fileName.equals(".") || fileName.equals("..")) {
continue;
}
System.out.println(fileName);
File localpath = new File(localPath);
File[] fileList = localpath.listFiles();
if (!localpath.exists()) {
localpath.mkdirs();
localPath = localpath.getPath();
}
for (File file : fileList) {
if (fileName.equals(file.getName())) {
file.delete();
}
}
System.out.println(localPath);
String localFileName = localPath + File.separator + fileName;
channelSftp.get(src + "/" + fileName, localPath);
close();
return true;
}
}
}catch(Exception e){
e.printStackTrace();
close();
}
return false;
}
/**
* @Description 下载目录下的指定文件
* @param host 上传主机IP
* @param port 端口 默认22
* @param userName 登录名
* @param password 密码
* @param src 服务器文件目录
* @param localPath 本地存放地址
* @param fileName 指定文件名
* @return boolean
*/
public static boolean downloadFile(String host, int port, String userName, String password, String src, String localPath,String fileName){
try{
//建立连接
if (channelSftp == null || !channelSftp.isConnected()) {
channelSftp=getSFTPClient(host,password,userName,port);
}
System.out.println(src);
// 下载文件的存放地址不存在则自动新建目录
File localpath = new File(localPath);
if (!localpath.exists()) {
localpath.mkdirs();
localPath = localpath.getPath();
}
channelSftp.get(src + "/" + fileName , localPath);
close();
return true;
}catch(Exception e){
e.printStackTrace();
close();
}
return false;
}
}
接口测试,使用postman测试
/**
* 上传文件到服务器
* @param request
* @param file
* @return
* @throws IOException
*/
@RequestMapping(value = "/upload",method = RequestMethod.POST)
public String upload(HttpServletRequest request, MultipartFile file) throws IOException {
// 获取到上传文件的名字
String fileName = file.getOriginalFilename();
// 转换成输入流的方式
InputStream inputStream = file.getInputStream();
// 在这里可以修改的文件名称
/*String imagesuffix = fileName.substring(fileName.lastIndexOf("."));//获取文件后缀
String filename="上传"+imagesuffix;//拼接成你想要的名字*/
// host sftp地址
String host = "1.1.1.1";
// port sftp端口
int port = 22;
// userName 登录名
String userName = "root";
// password 密码
String password = "root";
// remoteFile sftp服务器文件存放路径
String remoteFile = "/home/atc/upload";
boolean root = UploadFileUtil.uploadFile(host,port,userName,password,remoteFile,inputStream,fileName);
return "1";
}
/**
* 上传文件夹到服务器
* @param request
* @param file
* @return
* @throws IOException
*/
@RequestMapping(value = "/uploadDir",method = RequestMethod.POST)
public String uploadDir(HttpServletRequest request,MultipartFile[] file) throws IOException {
if (file!=null) {
// host sftp地址
String host = "1.1.1.1";
// port sftp端口
int port = 22;
// userName 登录名
String userName = "root";
// password 密码
String password = "root";
// remoteFile sftp服务器文件存放路径
String remoteFile = "/home/atc/upload";
boolean root = UploadFileUtil.uploadDstFile(host,port,userName,password,file,remoteFile);
}
return "";
}
/**
* 下载服务器指定文件
* @param src 文件所在位置+文件名
* @param fileName 指定文件名
* @return
* @throws IOException
*/
@RequestMapping(value = "/download",method = RequestMethod.POST)
public String download(String src,String fileName) throws IOException {
// host sftp地址
String host = "1.1.1.1";
// port sftp端口
int port = 22;
// userName 登录名
String userName = "root";
// password 密码
String password = "root";
// String path = "/home/atc/upload/"+fileName;
String localPath = "/Users/Desktop/download/";
boolean result = UploadFileUtil.downloadFile(host,port,userName,password,src,localPath,fileName);
return "1";
}
视频上传需在配置文件中配置文件大小
# 视频上传配置文件大小,根据需求配置
spring.servlet.multipart.max-file-size = 9967920994
spring.servlet.multipart.max-request-size = 9967920994