JAVA FTPClient文件操作

import com.gallery.constants.FtpConstants;
import com.gallery.framework.api.ErrorStatusEnum;
import com.gallery.framework.exception.BizException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

import java.io.IOException;

/**
* @Author: Yilia
* @Date: 2022/5/6/0006 14:42
*/

public class FtpUtils {
protected final static Logger logger = Logger.getLogger(FtpUtils.class);

/**
* 创建ftp连接
* @return
* @throws IOException
*/
public static FTPClient getFTPClient() throws IOException {
//创建ftp客户端
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
//链接ftp服务器
ftpClient.connect(FtpConstants.HOSTNAME, FtpConstants.PORT);
// 修改连接模式 服务器需要使用被动模式
ftpClient.enterLocalPassiveMode();
//登录ftp
ftpClient.login(FtpConstants.USERNAME, FtpConstants.PASSWORD);
int reply = ftpClient.getReplyCode();
//如果reply返回230就算成功了,如果返回530密码用户名错误或当前用户无权限下面有详细的解释。
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new BizException(ErrorStatusEnum.RESOURCE_IN_USE.getCode(), "ftp连接失败");
}
return ftpClient;
}

/**
* 关闭FTP方法
* @param ftp
* @return
*/
public static void closeFTP(FTPClient ftp){
try {
ftp.logout();
} catch (Exception e) {
logger.error("FTP关闭失败");
}finally{
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
logger.error("FTP关闭失败");
}
}
}
}

}
文件上传
public void uploadFile(MultipartFile file, String toPath, String fileName) throws IOException {
FTPClient ftpClient = FtpUtils.getFTPClient();
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);

ftpClient.storeFile(fileName, file.getInputStream());
FtpUtils.closeFTP(ftpClient);
}
文件下载
/**
* 文件下载
* @param response
* @param fromPath 下载路径
* @param fileName 下载文件名
* @throws IOException
*/
public void downloadFileOption(HttpServletResponse response, String fromPath, String fileName) throws IOException {
OutputStream outputStream = null;
FTPClient ftpClient = FtpUtils.getFTPClient();
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(fromPath);

FTPFile[] files = ftpClient.listFiles();
for (FTPFile file : files) {
// 取得指定文件并下载
if (file.getName().equals(fileName)) {
outputStream = response.getOutputStream();
boolean flag = ftpClient.retrieveFile(file.getName(), outputStream);
outputStream.flush();
outputStream.close();

if (!flag) {
logger.info("文件下载失败");
}
}
}
FtpUtils.closeFTP(ftpClient);
}
文件复制粘贴
/**
* 文件粘贴操作
* @param fromPath 文件所在路径
* @param toPath 粘贴目的所在路径
* @param fileName 文件名
* @param directory 是否文件夹
* @param option 拷贝/剪切
* @throws IOException
*/
public void pasteFileOperation(String fromPath, String toPath, String fileName, boolean directory, String option) throws IOException {
FTPClient ftpClient = FtpUtils.getFTPClient();
if (directory) {
// 目标路径下新建目录
fromPath = fromPath + fileName + "/";
ftpClient.changeWorkingDirectory(toPath);
ftpClient.makeDirectory(fileName);
toPath = toPath + fileName + "/";
dealDirectory(ftpClient, fromPath, toPath, option);
}else {
// 文件
// 跳转到文件目录
ftpClient.changeWorkingDirectory(fromPath);
boolean flag = false;
if (FILE_OPTION_COPY.equals(option)) {
// 复制
flag = copyFile(ftpClient, fileName, toPath);
}
if (FILE_OPTION_CUT.equals(option)) {
// 剪切
flag = ftpClient.rename(fromPath + fileName, toPath + fileName);
}

if(!flag){
logger.info("文件粘贴失败");
}
}
FtpUtils.closeFTP(ftpClient);
}

/**
* 文件夹处理
* @param ftpClient
* @param fromPath
* @param toPath
* @param option
* @throws IOException
*/
private void dealDirectory(FTPClient ftpClient, String fromPath, String toPath, String option) throws IOException {
// 进入原目录进行获取文件列表
ftpClient.changeWorkingDirectory(fromPath);
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.isDirectory()) {
// 目录
// 切换粘贴位置
ftpClient.changeWorkingDirectory(toPath);
// 复制目录
if (!ftpClient.makeDirectory(ftpFile.getName())) {
FtpUtils.closeFTP(ftpClient);
logger.error("目录复制失败");
}
dealDirectory(ftpClient, fromPath + ftpFile.getName() + "/", toPath + ftpFile.getName() + "/", option);
}else {
// 文件
// 进入原目录进行复制操作
ftpClient.changeWorkingDirectory(fromPath);
boolean flag = false;
if (FILE_OPTION_COPY.equals(option)) {
// 复制
flag = copyFile(ftpClient, ftpFile.getName(), toPath);
}
if (FILE_OPTION_CUT.equals(option)) {
// 剪切
flag = ftpClient.rename(fromPath + ftpFile.getName(), toPath + ftpFile.getName());
}

if(!flag){
FtpUtils.closeFTP(ftpClient);
logger.error("文件粘贴失败");
}
}
}

ftpClient.changeWorkingDirectory(fromPath);
if (FILE_OPTION_CUT.equals(option) && ftpClient.listFiles().length == 0) {
// 剪切
boolean flag = ftpClient.removeDirectory(fromPath);
if(!flag){
FtpUtils.closeFTP(ftpClient);
logger.error("文件粘贴失败");
}
}
}

/**
* 复制文件到指定位置
* @param ftpClient
* @param fileName 文件名
* @param toPath 目标路径
* @return
* @throws IOException
*/
private boolean copyFile(FTPClient ftpClient, String fileName, String toPath) throws IOException {
//读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
ByteArrayOutputStream out = new ByteArrayOutputStream();
ftpClient.retrieveFile(new String(fileName.getBytes("UTF-8"),"ISO-8859-1"), out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
//文件复制,先读,再写
//二进制
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
boolean fileState = ftpClient.storeFile(toPath + (new String(fileName.getBytes("UTF-8"), "ISO-8859-1")), in);
out.flush();
out.close();
in.close();
return fileState;
}
文件删除
/**
* 删除文件操作
* @param fromPath 文件所在路径
* @param fileName 文件名
* @param directory 是否目录
* @throws IOException
*/
public void deleteFileOperation(String fromPath, String fileName, boolean directory) throws IOException {
FTPClient ftpClient = FtpUtils.getFTPClient();
ftpClient.changeWorkingDirectory(fromPath);
if (directory) {
deleteDirectory(ftpClient, fromPath + fileName + "/");
}else {
if(!ftpClient.deleteFile(fileName)){
logger.error("删除文件失败");
}
}
FtpUtils.closeFTP(ftpClient);
}

/**
* 删除文件夹
* @param ftpClient
* @param fromPath
* @throws Exception
*/
private void deleteDirectory(FTPClient ftpClient, String fromPath) throws IOException {
// 进入原目录进行获取文件列表
ftpClient.changeWorkingDirectory(fromPath);
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.isDirectory()) {
// 目录
deleteDirectory(ftpClient, fromPath + ftpFile.getName() + "/");
} else {
// 文件
// 进入原目录进行删除操作
ftpClient.changeWorkingDirectory(fromPath);
if(!ftpClient.deleteFile(ftpFile.getName())){
FtpUtils.closeFTP(ftpClient);
logger.error("文件删除失败");
}
}
}

ftpClient.changeWorkingDirectory(fromPath);
if (ftpClient.listFiles().length == 0) {
// 删除文件夹
if(!ftpClient.removeDirectory(fromPath)){
FtpUtils.closeFTP(ftpClient);
logger.error("文件删除失败");
}
}
}
压缩文件
/**
* 压缩文件操作
* @param fromPath 文件所在路径
* @param fileName 文件名称
* @param toPath 压缩后的路径
* @param compressName 压缩后的名称
* @param format 压缩格式 tar.gz/zip/rar
* @throws IOException
*/
public void compressFileOperation(String fromPath, String fileName, String toPath, String compressName, String format) throws IOException {
// 拼接文件完整路径
String fromFile = ROOT_PATH + fromPath + fileName;
String cachePath = FILE_CACHE + fileName + "." + format;
File sourceFile = new File(fromFile);

// 压缩文件
FileOutputStream fileOutputStream = new FileOutputStream(cachePath);
if (FILE_COMPRESS_GZ.equals(format)) {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new BufferedOutputStream(fileOutputStream));
TarArchiveOutputStream tarArchive = new TarArchiveOutputStream(gzipOutputStream);
// 使文件名支持超过 100 个字节
tarArchive.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
compressTarGZ(sourceFile, fileName, tarArchive);
tarArchive.close();
gzipOutputStream.close();

}else if (FILE_COMPRESS_ZIP.equals(format) || FILE_COMPRESS_RAR.equals(format)) {
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
compressZip(sourceFile, fileName, zipOutputStream);
zipOutputStream.flush();
zipOutputStream.close();
}
fileOutputStream.close();

// 上传到ftp
FTPClient ftpClient = FtpUtils.getFTPClient();
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);
FileInputStream fileInputStream = new FileInputStream(new File(cachePath));
boolean flag = ftpClient.storeFile(compressName, fileInputStream);
if(!flag){
logger.error("压缩文件失败");
}

fileInputStream.close();
FtpUtils.closeFTP(ftpClient);

// 删除临时文件
File cacheFile = new File(cachePath);
if (cacheFile.exists()) {
boolean delete = cacheFile.delete();
if (!delete) {
logger.error("BizException:压缩缓存文件删除失败");
}
}
}

/**
* 压缩成gz格式文件
* @param sourceFile
* @param fileName
* @param tarArchive
* @throws IOException
*/
private void compressTarGZ(File sourceFile, String fileName, TarArchiveOutputStream tarArchive) throws IOException {
tarArchive.putArchiveEntry(new TarArchiveEntry(sourceFile, fileName));
if (sourceFile.isDirectory()) {
// 目录
tarArchive.closeArchiveEntry();
// 遍历文件夹下的文件
for (File file : sourceFile.listFiles()) {
// 递归遍历文件目录树
compressTarGZ(file, fileName + "\\" + file.getName(), tarArchive);
}
}else if (sourceFile.isFile()) {
// 文件
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
try {
fileInputStream = new FileInputStream(sourceFile);
bufferedInputStream = new BufferedInputStream(fileInputStream);
// 写入文件
IOUtils.copy(bufferedInputStream, tarArchive);
tarArchive.closeArchiveEntry();
} catch (IOException e) {
logger.error("IOException:" + e);
}finally {
try {
if (null != bufferedInputStream) {
bufferedInputStream.close();
}
if (null != fileInputStream) {
fileInputStream.close();
}
}catch (IOException e) {
logger.error("IOException:" + e);
}
}
}
}

/**
* 压缩成zip格式文件
* @param sourceFile
* @param fileName
* @param zipOutputStream
* @throws IOException
*/
private void compressZip(File sourceFile, String fileName, ZipOutputStream zipOutputStream) throws IOException {
if (sourceFile.isDirectory()) {
// 目录
// 目录创建要带斜杠 否则会创建文件
zipOutputStream.putNextEntry(new ZipEntry(fileName + "/"));
// 遍历文件夹下的文件
for (File file : sourceFile.listFiles()) {
// 递归遍历文件目录树
compressZip(file, fileName + "/" + file.getName(), zipOutputStream);
}
}else if (sourceFile.isFile()) {
// 文件
zipOutputStream.putNextEntry(new ZipEntry(fileName));
FileInputStream in = null;
try {
in = new FileInputStream(sourceFile);
byte[] bytes = new byte[1024];
int num = -1;
while ((num = in.read(bytes, 0, bytes.length)) != -1) {
zipOutputStream.write(bytes, 0, num);
}
} catch (IOException e) {
logger.error("IOException:" + e);
}finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
logger.error("IOException:" + e);
}
}
}
}
}
解压文件
/**
* 解压文件操作
* @param fromPath 文件所在路径
* @param fileName 文件名
* @param toPath 解压到路径
* @param format 压缩格式 tar.gz/zip/rar
* @throws IOException
*/
public void decompressFileOperation(String fromPath, String fileName, String toPath, String format) throws IOException {
String cachePath = FILE_CACHE + fileName;
FTPClient ftpClient = FtpUtils.getFTPClient();
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(fromPath);

// 获取压缩文件
OutputStream outputStream = new FileOutputStream(new File(cachePath));
ftpClient.retrieveFile(fileName, outputStream);
outputStream.close();

if (FILE_COMPRESS_GZ.equals(format)) {
// tar.gz
decompressionGz(ftpClient, cachePath, toPath);
}else if (FILE_COMPRESS_ZIP.equals(format) || FILE_COMPRESS_RAR.equals(format)) {
// zip/rar
decompressionZip(ftpClient, cachePath, toPath);
}
FtpUtils.closeFTP(ftpClient);

// 删除临时文件
File file = new File(cachePath);
if (file.exists()) {
boolean delete = file.delete();
if (!delete) {
logger.error("删除缓存文件失败");
}
}
}

/**
* 解压gz文件
* @param ftpClient
* @param cachePath
* @param toPath
*/
private void decompressionGz(FTPClient ftpClient, String cachePath, String toPath) throws IOException {
InputStream inputStream = new FileInputStream(cachePath);
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipInputStream);
TarArchiveEntry tarArchiveEntry = null;

while( (tarArchiveEntry = tarArchiveInputStream.getNextTarEntry()) != null ){
String entryName = tarArchiveEntry.getName();

if(tarArchiveEntry.isDirectory()){
// 目录
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);
// 创建文件夹
ftpClient.makeDirectory(entryName);
ftpClient.changeWorkingDirectory(entryName);
}else{
//文件
ByteArrayOutputStream out = new ByteArrayOutputStream();

//读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
byte[] array = new byte[1024];
int num = -1;
while ((num = tarArchiveInputStream.read(array, 0, array.length)) != -1) {
out.write(array, 0, num);
}

ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);
ftpClient.storeFile(entryName, in);
out.flush();
out.close();
in.close();
}
}

tarArchiveInputStream.close();
gzipInputStream.close();
inputStream.close();
}

/**
* 解压zip、rar文件
* @param ftpClient
* @param cachePath
* @param toPath
*/
private void decompressionZip(FTPClient ftpClient, String cachePath, String toPath) throws IOException {
FileInputStream fileInputStream = new FileInputStream(cachePath);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
ZipEntry zipEntry = null;

while( (zipEntry = zipInputStream.getNextEntry()) != null ){
String entryName = zipEntry.getName();

if(zipEntry.isDirectory()){
// 目录
// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);
// 创建文件夹
ftpClient.makeDirectory(entryName);
ftpClient.changeWorkingDirectory(entryName);
}else{
//文件
ByteArrayOutputStream out = new ByteArrayOutputStream();

//读取文件,使用下载文件的方法把文件写入内存,绑定到out流上
byte[] array = new byte[1024];
int num = -1;
while ((num = zipInputStream.read(array, 0, array.length)) != -1) {
out.write(array, 0, num);
}

ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

// 设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
// 设置二进制传输,使用BINARY_FILE_TYPE,ASC容易造成文件损坏
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.changeWorkingDirectory(toPath);
// 创建文件
ftpClient.storeFile(entryName, in);
out.flush();
out.close();
in.close();
}
}
zipInputStream.close();
fileInputStream.close();
}
ftp日志打印
import java.io.OutputStream;
import org.apache.log4j.Logger;

public class LogOutputStream extends OutputStream {
private final Logger logger;
/** The internal memory for the written bytes. */
private StringBuffer mem;

public LogOutputStream(final Logger logger) {
this.logger = logger;
mem = new StringBuffer();
}

@Override
public void write(final int b) {
if ( (char) b == '\n' ) {
flush();
return;
}
mem = mem.append((char)b);
}

@Override
public void flush() {
logger.info(mem.toString());
mem = new StringBuffer();
}
}
protected final static Logger logger = Logger.getLogger(FtpUtils.class);

// 打印ftp日志
ftpClient.addProtocolCommandListener(
new PrintCommandListener(
new PrintWriter(new OutputStreamWriter(new LogOutputStream(logger), "UTF-8")), true));
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值