import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.ftp.FtpException;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: FTPTools
* @Description: TODO
* @author
* @date 2021-8-5
*
*/
public class FTPTools {
/** 地址 */
public static final String DEFAULT_HOST = "127.0.0.1";
/** 端口 */
public static final int DEFAULT_PORT = 21;
/** 用户 */
public static final String DEFAULT_USER = "ftp";
/** 密码 */
public static final String DEFAULT_PASSWORD = "admin_ftp";
private static int clientTimeout = 1000 * 30;
//用于打印日志
private static final Logger log = Logger.getLogger(FTPTools.class);
/**
* 进入文件夹
* @param ftpClient
* @param directory 文件路径
* @return
*/
public static boolean cd(FTPClient ftpClient,String directory) {
if (StrUtil.isBlank(directory)) {
return false;
}
boolean flag = true;
try {
flag = ftpClient.changeWorkingDirectory(directory);
} catch (IOException e) {
throw new FtpException(e);
}
return flag;
}
/**
* 逻辑判断创建文件夹
* @param ftpClient
* @param dir 文件路径
*/
public static void mkDirs(FTPClient ftpClient,String dir) {
final String[] dirs = StrUtil.trim(dir).split("[\\\\/]+");
final String now = pwd(ftpClient);
if(dirs.length > 0 && StrUtil.isEmpty(dirs[0])) {
//首位为空,表示以/开头
cd(ftpClient,StrUtil.SLASH);
}
for (int i = 0; i < dirs.length; i++) {
if (StrUtil.isNotEmpty(dirs[i])) {
if (false == cd(ftpClient,dirs[i])) {
//目录不存在时创建
mkdir(ftpClient,dirs[i]);
cd(ftpClient,dirs[i]);
}
}
}
// 切换回工作目录
cd(ftpClient,now);
}
/**
* 创建文件夹
* @param ftpClient
* @param dir 文件路径
* @return
*/
public static boolean mkdir(FTPClient ftpClient,String dir) {
boolean flag = true;
try {
flag = ftpClient.makeDirectory(dir);
} catch (IOException e) {
throw new FtpException(e);
}
return flag;
}
/**
*
* @param ftpClient
* @return
*/
public static String pwd(FTPClient ftpClient) {
try {
return ftpClient.printWorkingDirectory();
} catch (IOException e) {
throw new FtpException(e);
}
}
/**
*
* @param workingPath 服务器的工作目
* @param inputStream 要上传文件的输入流
* @param saveName 文件保存路径名称
* @return
*/
public static boolean upload(String workingPath, InputStream inputStream, String saveName) {
return upload(DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD,workingPath, inputStream, saveName);
}
/**
* 上传
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param workingPath 服务器的工作目
* @param inputStream 要上传文件的输入流
* @param saveName 设置上传之后的文件名
* @return
*/
public static boolean upload(String hostname, int port, String username, String password, String workingPath, InputStream inputStream, String saveName) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
ftpClient.setDefaultTimeout(clientTimeout * 1000);
ftpClient.setBufferSize(1024*1024);
ftpClient.setDataTimeout(clientTimeout * 1000);
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
String pwd = pwd(ftpClient);
if (StrUtil.isNotBlank(workingPath)) {
mkDirs(ftpClient,workingPath);
boolean isOk = cd(ftpClient,workingPath);
if (false == isOk) {
return false;
}
}
// 3 检查是否上传成功
if (storeFile(ftpClient, saveName, inputStream)) {
flag = true;
disconnect(ftpClient);
}
}
return flag;
}
/**
* 断开连接
*
* @param ftpClient
* @throws Exception
*/
public static void disconnect(FTPClient ftpClient) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
log.error("已关闭连接");
} catch (IOException e) {
log.error("没有关闭连接");
e.printStackTrace();
}
}
}
/**
* 测试是否能连接
*
* @param ftpClient
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @return 返回真则能连接
*/
public static boolean connect(FTPClient ftpClient, String hostname, int port, String username, String password) {
boolean flag = false;
try {
//ftp初始化的一些参数
ftpClient.connect(hostname, port);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("UTF-8");
if (ftpClient.login(username, password)) {
log.info("连接ftp成功");
flag = true;
} else {
log.error("连接ftp失败,可能用户名或密码错误");
try {
disconnect(ftpClient);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
log.error("连接失败,可能ip或端口错误");
e.printStackTrace();
}
return flag;
}
/**
* 上传文件
*
* @param ftpClient
* @param saveName 全路径。如/home/public/a.txt
* @param fileInputStream 要上传的文件流
* @return
*/
public static boolean storeFile(FTPClient ftpClient, String saveName, InputStream fileInputStream) {
boolean flag = false;
try {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //处理好编码,防止乱码
if (ftpClient.storeFile(saveName, fileInputStream)) {
flag = true;
log.error("上传成功");
disconnect(ftpClient);
}
} catch (IOException e) {
log.error("上传失败");
disconnect(ftpClient);
e.printStackTrace();
}
return flag;
}
/**
* 下载文件
*
* @param filename 需要下载的文件全路径
* @return
*/
public static InputStream downFileByPath(String fileName)
{
InputStream in=null;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD)) {
try {
in = ftpClient.retrieveFileStream(fileName);
disconnect(ftpClient);
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return in;
}
/**
* 1 多文件下载
* @param response HttpServletResponse
* @param files[] 待下载文件
* @param downloadfile 下载文件文件名+文件类型(a.zip)
* @throws Exception
* @date 2019年3月29日11:31:35
*/
public static void multFileDownload(HttpServletResponse response,List<Map<String,Object>> listF,String downloadfile) throws Exception {
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("content-type", "application/octet-stream");
response.setContentType("multipart/form-data");//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setHeader("Content-Disposition", "attachment;fileName="+downloadfile);
try {
ZipOutputStream zipstream=new ZipOutputStream(response.getOutputStream());
DataInputStream dis=null;
for (Map<String,Object> file:listF) {
InputStream instream =(InputStream)file.get("is");
String fileName =file.get("file").toString();
if (instream==null) {
continue;
}
dis=new DataInputStream(new BufferedInputStream(instream));
ZipEntry entry = new ZipEntry(fileName);
zipstream.putNextEntry(entry);
byte[] b = new byte[1024];
int length;
while((length=instream.read(b))>0){
zipstream.write(b,0,length);
}
instream.close();
if(dis!=null){
dis.close();
}
zipstream.closeEntry();
zipstream.flush();
}
zipstream.finish();
zipstream.close();
} catch (IOException e) {
new RuntimeException(e.getMessage());
}
}
/**
* 下载文件并且重命名
*
* @param fullFile 文件全路径
* @param changename 修改的文件名
*/
public static boolean downFile(String fullFile,String changename)
{
return downFile(DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD,fullFile,changename);
}
/**
* 下载文件
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param fullFile 文件全路径
* @param changename 修改的文件名
* @return
*/
public static boolean downFile(String hostname, int port, String username, String password, String fullFile,String changename)
{
boolean flag = false;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
try {
flag = true;
File file=new File(fullFile);
OutputStream os = new FileOutputStream(file);
//ftpClient.setControlEncoding("GBK");
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //处理好编码,防止乱码
//如果文件名中含有中文,retrieveFile文件时会找不到FTP上的文件,导致保存在本地的是一个空文件,所以也要转换一下
ftpClient.retrieveFile(changename, os);
os.close();
disconnect(ftpClient);
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return flag;
}
/**
* 下载文件
*
* @param fullFile 文件全路径
* @param changename 修改的文件名
* @param os 文件输出流
* @return
*/
public static boolean downFile(String fullFile,String changename,OutputStream os)
{
return downFile(DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD,fullFile,changename,os);
}
/**
* 下载文件
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param fullFile 文件全路径
* @param changename 修改的文件名
* @param os 文件输出流
* @return
*/
public static boolean downFile(String hostname, int port, String username, String password, String fullFile,String changename,OutputStream os)
{
boolean flag = false;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
try {
flag = true;
//ftpClient.setControlEncoding("GBK");
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //处理好编码,防止乱码
//如果文件名中含有中文,retrieveFile文件时会找不到FTP上的文件,导致保存在本地的是一个空文件,所以也要转换一下
ftpClient.retrieveFile(changename, os);
os.close();
disconnect(ftpClient);
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return flag;
}
/**
* 是否存在文件
* @param fullFile
* @return
*/
public static boolean existFile(String fullFile)
{
return existFile(DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD,fullFile);
}
/**
* 查看文件是否存在
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param fullFile 文件全路径
* @return
*/
public static boolean existFile(String hostname, int port, String username, String password, String fullFile)
{
boolean flag = false;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
try {
//2 检查工作目录是否存在
FTPFile[] files = ftpClient.listFiles(fullFile);
if(files!=null&&files.length>0){
flag = true;
disconnect(ftpClient);
}
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return flag;
}
/**
* 删除文件
* @param fullFile
* @return
*/
public static boolean deleteFile(String fullFile) {
return deleteFile(DEFAULT_HOST,DEFAULT_PORT,DEFAULT_USER,DEFAULT_PASSWORD,fullFile);
}
/**
* 删除文件
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param fullFile 文件全路径
* @return
*/
public static boolean deleteFile(String hostname, int port, String username, String password, String fullFile)
{
boolean flag = false;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
try {
if(ftpClient.deleteFile(fullFile)){
flag = true;
disconnect(ftpClient);
}
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return flag;
}
public static void main(String[] args) {
//Login failed for user [anonymous], reply code is: [530]
InputStream is=FileUtil.getInputStream("F:/学习开发经验连接.txt");
upload("/demo",is ,"111.txt");
}
}
FTP工具类
于 2021-08-23 15:27:07 首次发布