package org.dromara.system.uitil;
import cn.hutool.extra.ftp.Ftp;
import org.apache.commons.lang3.StringUtils;
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.dromara.system.domain.properties.FtpConfig;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/**
* 实现FTP文件上传和文件下载
*/
public class FtpApche {
private static FTPClient ftpClient = new FTPClient();
private static String encoding = System.getProperty("file.encoding");
/**
* 超时时间
*/
private static final int DEFAULT_TIMEOUT = 60 * 1000;
/**
* 连接到ftp
*/
public static void connect(FtpConfig config) throws IOException {
setTimeout();
try {
ftpClient.connect(config.getUrl(), 21);
} catch (UnknownHostException e) {
throw new IOException("Can't find FTP server :" + "21");
}
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
disconnect();
throw new IOException("Can't connect to server :" + "21");
}
if (!ftpClient.login(config.getUsername(), config.getPasswd())) {
disconnect();
throw new IOException("Can't login to server :" + "21");
}
// set data transfer mode.
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// Use passive mode to pass firewalls.
ftpClient.enterLocalPassiveMode();
}
/**
* 设置超时时间
*/
private static void setTimeout() {
ftpClient.setDefaultTimeout(DEFAULT_TIMEOUT);
ftpClient.setConnectTimeout(DEFAULT_TIMEOUT);
ftpClient.setDataTimeout(DEFAULT_TIMEOUT);
}
/**
* ftp是否处于连接状态,是连接状态返回true
*
* @return boolean 是连接状态返回true
*/
public static boolean isConnected() {
return ftpClient.isConnected();
}
/**
* 关闭ftp连接
*/
public static void disconnect() {
if (null != ftpClient && ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException ex) {
// do nothing
}
}
}
/**
* 改变工作目录
*
* @param dir ftp服务器上目录
* @return boolean 改变成功返回true
*/
public static boolean changeWorkingDirectory(String dir) {
try {
return ftpClient.changeWorkingDirectory(dir);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* Description: 向FTP服务器上传文件
*
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(FtpConfig config, MultipartFile file, String name) throws IOException {
boolean result = false;
InputStream input = file.getInputStream();
try {
connect(config);
ftpClient.setBufferSize(1024 * 1024);
result = ftpClient.storeFile(new String(name.getBytes(encoding), "iso-8859-1"), input);
if (result) {
System.out.println("上传成功!");
}
input.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
ftpClient.logout();
ftpClient.disconnect();
}
return result;
}
/**
* 根据文件ftp路径名称删除文件
*
* @param ftpFileName 文件ftp路径名称
*/
public static void deleteFile(String ftpFileName) throws IOException {
int dele = ftpClient.dele(ftpFileName);
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据uploadFile返回的路径,从ftp下载文件到指定输出流中
*
* @param filename 文件名称
*/
public static InputStream downloadFileFromDailyDir(String filename) throws IOException {
return ftpClient.retrieveFileStream(filename);
}
public static List downloadList(FtpConfig config) throws IOException {
connect(config);
List list = new ArrayList<>();
FTPFile[] ftpFiles = ftpClient.listFiles();
if (ftpFiles.length == 0) {
return list;
}
for (FTPFile ftpFile : ftpFiles) {
list.add(ftpFile.getName());
}
return list;
}
/**
* 根据名称获取文件,以字节数组返回
*
* @param ftpPath FTP服务器文件相对路径,例如:test/123
* @param fileName 文件名,例如:test.xls
* @return byte[] 字节数组对象
*/
public static byte[] getFileBytesByName(InputStream is) throws IOException {
//创建byte数组输出流
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
try {
byte[] buffer = new byte[1024 * 1024 * 4];
int len = -1;
while ((len = is.read(buffer, 0, 1024 * 1024 * 4)) != -1) {
byteStream.write(buffer, 0, len);
}
} catch (Exception e) {
System.out.println(e);
}
} catch (Exception e) {
e.printStackTrace();
}
return byteStream.toByteArray();
}
}