You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
12 KiB
353 lines
12 KiB
package com.dxhy.oss.service;
|
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
import com.dxhy.oss.utils.SftpPool;
|
|
import com.jcraft.jsch.ChannelSftp;
|
|
import com.jcraft.jsch.SftpException;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.commons.net.ftp.FTP;
|
|
import org.apache.commons.net.ftp.FTPClient;
|
|
import org.apache.commons.net.ftp.FTPFile;
|
|
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.file.Files;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* @author jiaohongyang
|
|
*/
|
|
@Slf4j
|
|
public class FtpService {
|
|
|
|
private final SftpPool pool;
|
|
|
|
public FtpService(SftpPool pool) {
|
|
this.pool = pool;
|
|
}
|
|
|
|
/**
|
|
* 将输入流的数据上传到sftp作为文件。文件完整路径 = basePath+directory
|
|
*
|
|
* @param pathName ftp服务保存地址,完整路径
|
|
* @param fileName 上传到ftp的文件名
|
|
* @param originFileName 待上传文件的名称(绝对地址)
|
|
*/
|
|
|
|
public boolean uploadFile(String pathName, String fileName, String originFileName) throws InterruptedException {
|
|
log.info("开始上传文件");
|
|
ChannelSftp sftp = null;
|
|
InputStream inputStream;
|
|
try {
|
|
sftp = pool.borrowObject();
|
|
try {
|
|
sftp.cd(pathName);
|
|
} catch (SftpException e) {
|
|
// 目录不存在,则创建文件夹
|
|
String[] dirs = pathName.split("/");
|
|
String tempPath = "";
|
|
for (String dir : dirs) {
|
|
if (null == dir || "".equals(dir)) {
|
|
continue;
|
|
}
|
|
tempPath += "/" + dir;
|
|
try {
|
|
sftp.cd(tempPath);
|
|
} catch (SftpException ex) {
|
|
try {
|
|
sftp.mkdir(tempPath);
|
|
sftp.cd(tempPath);
|
|
} catch (SftpException e1) {
|
|
e1.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
File orgFile = new File(originFileName);
|
|
inputStream = Files.newInputStream(orgFile.toPath());
|
|
sftp.put(inputStream, fileName);
|
|
inputStream.close();
|
|
// 删除本地文件,防止服务器空间不足
|
|
FileUtil.del(orgFile);
|
|
log.info("上传文件成功");
|
|
return true;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
log.info("上传文件失败");
|
|
return false;
|
|
} finally {
|
|
if (sftp != null) {
|
|
log.info("回收线程");
|
|
pool.returnObject(sftp);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public static boolean uploadFile(FTPClient ftpClient, String serviceDec, String fileName, InputStream inputStream) {
|
|
try {
|
|
log.info("开始上传文件");
|
|
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
|
createDirecroty(ftpClient, serviceDec);
|
|
ftpClient.makeDirectory(serviceDec);
|
|
ftpClient.changeWorkingDirectory(serviceDec);
|
|
ftpClient.storeFile(fileName, inputStream);
|
|
inputStream.close();
|
|
ftpClient.logout();
|
|
log.info("上传文件成功");
|
|
} catch (Exception e) {
|
|
log.error("上传文件失败" + e);
|
|
} finally {
|
|
try {
|
|
if (ftpClient.isConnected()) {
|
|
ftpClient.disconnect();
|
|
}
|
|
if (null != inputStream) {
|
|
inputStream.close();
|
|
}
|
|
} catch (IOException e) {
|
|
log.error("上传文件失败" + e);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static boolean createDirecroty(FTPClient ftpClient, String remote) throws IOException {
|
|
boolean success = true;
|
|
String directory = remote + "/";
|
|
// 如果远程目录不存在,则递归创建远程服务器目录
|
|
if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(ftpClient, new String(directory))) {
|
|
int start = 0;
|
|
int end = 0;
|
|
if (directory.startsWith("/")) {
|
|
start = 1;
|
|
} else {
|
|
start = 0;
|
|
}
|
|
end = directory.indexOf("/", start);
|
|
String path = "";
|
|
String paths = "";
|
|
while (true) {
|
|
String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
|
|
path = path + "/" + subDirectory;
|
|
if (!existFile(ftpClient, path)) {
|
|
if (makeDirectory(ftpClient, subDirectory)) {
|
|
changeWorkingDirectory(ftpClient, subDirectory);
|
|
} else {
|
|
log.info("创建目录[" + subDirectory + "]失败");
|
|
changeWorkingDirectory(ftpClient, subDirectory);
|
|
}
|
|
} else {
|
|
changeWorkingDirectory(ftpClient, subDirectory);
|
|
}
|
|
|
|
paths = paths + "/" + subDirectory;
|
|
start = end + 1;
|
|
end = directory.indexOf("/", start);
|
|
// 检查所有目录是否创建完毕
|
|
if (end <= start) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
//改变目录路径
|
|
private static boolean changeWorkingDirectory(FTPClient ftpClient, String directory) {
|
|
boolean flag = true;
|
|
try {
|
|
flag = ftpClient.changeWorkingDirectory(directory);
|
|
if (flag) {
|
|
log.info("进入文件夹" + directory + " 成功!");
|
|
|
|
} else {
|
|
log.info("进入文件夹" + directory + " 失败!开始创建文件夹");
|
|
}
|
|
} catch (IOException ioe) {
|
|
ioe.printStackTrace();
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
//判断ftp服务器文件是否存在
|
|
private static boolean existFile(FTPClient ftpClient, String path) throws IOException {
|
|
boolean flag = false;
|
|
FTPFile[] ftpFileArr = ftpClient.listFiles(path);
|
|
if (ftpFileArr.length > 0) {
|
|
flag = true;
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
//创建目录
|
|
private static boolean makeDirectory(FTPClient ftpClient, String dir) {
|
|
boolean flag = true;
|
|
try {
|
|
flag = ftpClient.makeDirectory(dir);
|
|
if (flag) {
|
|
log.info("创建文件夹" + dir + " 成功!");
|
|
|
|
} else {
|
|
log.info("创建文件夹" + dir + " 失败!");
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
/**
|
|
* 获取FTP某一特定目录下的所有文件名称
|
|
*
|
|
* @param ftpClient 已经登陆成功的FTPClient
|
|
* @param ftpDirPath FTP上的目标文件路径
|
|
*/
|
|
public static List getFileNameList(FTPClient ftpClient, String ftpDirPath) {
|
|
List list = new ArrayList();
|
|
try {
|
|
if (ftpDirPath.startsWith("/") && ftpDirPath.endsWith("/")) {
|
|
// 通过提供的文件路径获取FTPFile对象列表
|
|
FTPFile[] files = ftpClient.listFiles(ftpDirPath);
|
|
// 遍历文件列表,打印出文件名称
|
|
for (int i = 0; i < files.length; i++) {
|
|
FTPFile ftpFile = files[i];
|
|
// 此处只打印文件,未遍历子目录(如果需要遍历,加上递归逻辑即可)
|
|
if (ftpFile.isFile()) {
|
|
// log.info(ftpDirPath + ftpFile.getName());
|
|
list.add(ftpFile.getName());
|
|
}
|
|
}
|
|
log.info("当前FTP路径可用");
|
|
} else {
|
|
log.info("当前FTP路径不可用");
|
|
}
|
|
} catch (IOException e) {
|
|
log.error("错误" + e);
|
|
}
|
|
return list;
|
|
}
|
|
public File downloadFile(FTPClient ftpClient, String servicePath, String fileName, String localFilePath) {
|
|
String name = dowFile(ftpClient, servicePath, fileName, localFilePath);
|
|
if (name != null && !name.equals("")){
|
|
return new File(fileName);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static String dowFile(FTPClient ftpClient, String servicePath, String fileName, String localFilePath) {
|
|
InputStream is = null;
|
|
FileOutputStream fos = null;
|
|
try {
|
|
ftpClient.enterLocalPassiveMode();
|
|
is = ftpClient.retrieveFileStream(servicePath + fileName);// 获取ftp上的文件
|
|
fos = new FileOutputStream(new File(localFilePath + fileName));
|
|
// 文件读取方式一
|
|
int i;
|
|
byte[] bytes = new byte[1024];
|
|
while ((i = is.read(bytes)) != -1) {
|
|
fos.write(bytes, 0, i);
|
|
}
|
|
// 文件读取方式二
|
|
//ftpClient.retrieveFile(ftpFilePath, new FileOutputStream(new File(localFilePath)));
|
|
ftpClient.completePendingCommand();
|
|
log.info("FTP文件下载成功!");
|
|
} catch (Exception e) {
|
|
log.error("FTP文件下载失败!" + e);
|
|
} finally {
|
|
try {
|
|
if (fos != null) fos.close();
|
|
if (is != null) is.close();
|
|
} catch (IOException e) {
|
|
log.error("下载流关闭失败" + e);
|
|
return null;
|
|
}
|
|
}
|
|
return localFilePath + fileName;
|
|
}
|
|
|
|
public boolean downloadFile(String directory, String downloadFile, String saveFile) {
|
|
log.info("开始下载文件!");
|
|
ChannelSftp sftp = null;
|
|
try {
|
|
sftp = pool.borrowObject();
|
|
if (directory != null && !"".equals(directory)) {
|
|
sftp.cd(directory);
|
|
}
|
|
String file = saveFile + "/" + downloadFile;
|
|
File fileLocal = new File(file);
|
|
if (fileLocal.exists()) {
|
|
boolean delete = fileLocal.delete();
|
|
log.info("删除本地路径文件:{}", delete);
|
|
}
|
|
this.directoryIsExists(saveFile);
|
|
sftp.get(downloadFile, file);
|
|
log.info("下载文件成功!");
|
|
return true;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
log.info("下载文件失败!");
|
|
return false;
|
|
} finally {
|
|
if (sftp != null) {
|
|
log.info("回收线程");
|
|
pool.returnObject(sftp);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* 删除文件
|
|
*
|
|
* @param directory 要删除文件所在目录
|
|
* @param deleteFile 要删除的文件
|
|
* @return 返回是否删除成功
|
|
*/
|
|
|
|
public boolean deleteFile(String directory, String deleteFile) {
|
|
ChannelSftp sftp = null;
|
|
try {
|
|
sftp = pool.borrowObject();
|
|
sftp.cd(directory);
|
|
sftp.rm(deleteFile);
|
|
return true;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
return false;
|
|
} finally {
|
|
if (sftp != null) {
|
|
log.info("回收线程");
|
|
pool.returnObject(sftp);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void directoryIsExists(String path) {
|
|
File directory = new File(path);
|
|
if (directory.exists()) {
|
|
return;
|
|
}
|
|
|
|
if (!directory.mkdir()) {
|
|
return;
|
|
}
|
|
|
|
if (directory.canWrite()) {
|
|
return;
|
|
}
|
|
|
|
boolean setWritable = directory.setWritable(true);
|
|
log.info("是否创建文件 directoryIsExists :{} ", setWritable);
|
|
|
|
}
|
|
}
|
|
|