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.

354 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);
}
}