package com.ruoyi.web.controller.ftpServer;
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 java.io.*;
import java.net.SocketException;
public class FtpUtil {
/**
* 获取FTPClient对象
* @return
*/
public static FTPClient getFTPClient(String ftpHost,int ftpPort,String ftpUserName,String ftpPassword) {
FTPClient ftpClient = null;
boolean result = false;
try {
//创建一个ftp客户端
ftpClient = new FTPClient();
ftpClient.enterLocalActiveMode();
// 连接FTP服务器
ftpClient.connect(ftpHost, ftpPort);
// 登陆FTP服务器
ftpClient.login(ftpUserName, ftpPassword);
//是否成功登录服务器
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
throw new RuntimeException("未连接到FTP,用户名或密码错误。");
}
} catch (SocketException e) {
throw new RuntimeException("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
throw new RuntimeException("FTP的端口错误,请正确配置。");
}
return ftpClient;
}
/**
* Description: 向FTP服务器上传文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param basePath FTP服务器基础目录
* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
* @param filename 上传到FTP服务器上的文件名
* @param input 输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String host, int port, String username, String password, String basePath,String filePath, String filename, InputStream input) {
boolean result = false;
FTPClient ftp = new FTPClient();
int reply;
try {
ftp = getFTPClient(host,port,username,password);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
//切换到上传目录
if(!ftp.changeWorkingDirectory(basePath + filePath)){
//如果目录不存在,创建目录
String[] dirs = filePath.split("/");
String tempPath = basePath;
for (String dir :dirs) {
if (dir == null || "".equals(dir))
continue;
tempPath += "/" + dir;
if(!ftp.changeWorkingDirectory(tempPath)){
if(!ftp.makeDirectory(tempPath)){
return result;
}else{
ftp.changeWorkingDirectory(tempPath);
}
}
}
}
//处理上传文件后文件名为中文乱码
ftp.setControlEncoding("UTF-8");
//设置上传文件的类型为二进制类型
ftp.setFileType(FTP.BINARY_FILE_TYPE);
filename = new String(filename.getBytes("GBK"),"iso-8859-1");
//上传文件
if(!ftp.storeFile(filename,input)){
System.out.println(ftp.storeFile(filename,input));
return result;
}
input.close();
ftp.logout();
result = true;
} catch (Exception e) {
e.printStackTrace();
}finally {
if(ftp.isConnected()){
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/**
* Description: 从FTP服务器下载文件
* @param host FTP服务器hostname
* @param port FTP服务器端口
* @param username FTP登录账号
* @param password FTP登录密码
* @param remotePath FTP服务器上的相对路径
* @param fileName 要下载的文件名
* @param localPath 下载后保存到本地的路径
* @return
*/
public static boolean downloadFile(String host, int port, String username, String password, String remotePath,String fileName, String localPath) {
boolean result = false;
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("GBK");
try {
int reply;
ftp = getFTPClient(host,port,username,password);
reply = ftp.getReplyCode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftp.enterLocalPassiveMode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
FTPFile[] fs = ftp.listFiles();
String remoteFileName;
for (FTPFile ff : fs) {
remoteFileName = new String(ff.getName().getBytes("iso-8859-1"), "GBK");
if (remoteFileName.equals(fileName)) {
File localFile = new File(localPath + "/" + remoteFileName);
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(remoteFileName, is);
is.close();
}
}
ftp.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return result;
}
/**
* 从FTP服务器删除文件
*
* @param host
* 服务器IP地址
* @param port
* 服务器端口
* @param userName
* 用户登录名
* @param password
* 用户登录密码
* @param remotePath
* 服务器文件存储路径
* @param fileName
* 服务器文件存储名称
* @return
* <b>true</b>:删除成功
* <br/>
* <b>false</b>:删除失败
*/
public static boolean deleteFile (String host, int port, String userName, String password, String remotePath, String fileName) {
boolean result = false;
FTPClient ftp = new FTPClient();
// 设置字符编码
ftp.setControlEncoding("GBK");
try {
ftp = getFTPClient(host,port,userName,password);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftp.enterLocalPassiveMode();
// 判断返回码是否合法
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
// 不合法时断开连接
ftp.disconnect();
// 结束程序
return result;
}
// 设置文件操作目录
ftp.changeWorkingDirectory(remotePath);
// 设置文件类型,二进制
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
// 设置缓冲区大小
ftp.setBufferSize(3072);
// 获取文件操作目录下所有文件名称
FTPFile[] fs = ftp.listFiles();
String remoteFileName = "";
// 循环比对文件名称,判断是否含有当前要下载的文件名
for (FTPFile ff: fs) {
remoteFileName = new String(ff.getName().getBytes("iso-8859-1"), "GBK");
if (fileName.equals(remoteFileName)){
result = true;
}
}
// 文件名称比对成功时,进入删除流程
if (result) {
// 删除文件
result = ftp.deleteFile(new String(fileName.getBytes("GBK"),"iso-8859-1"));
}
// 登出服务器
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 判断连接是否存在
if (ftp.isConnected()) {
// 断开连接
ftp.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 递归遍历出目录下面所有文件
*
* @param pathName 需要遍历的目录,必须以"/"开始和结束
* @throws IOException
*/
public static List<FtpFileInfo> getFileList(String host, int port, String userName, String password,String pathName) throws IOException {
List<FtpFileInfo> ftpFileInfos = new ArrayList<>();
FTPClient ftp = new FTPClient();
// 设置字符编码
ftp.setControlEncoding("GBK");
ftp = getFTPClient(host,port,userName,password);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
ftp.enterLocalPassiveMode();
// 判断返回码是否合法
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
// 不合法时断开连接
ftp.disconnect();
}
if(pathName == null){
pathName = "/";
}
if (pathName.startsWith("/") && pathName.endsWith("/")) {
//更换目录到当前目录
//this.ftp.changeWorkingDirectory(new String(pathName.getBytes(), FTP.DEFAULT_CONTROL_ENCODING));
ftp.changeWorkingDirectory(new String(pathName.getBytes(), StandardCharsets.ISO_8859_1));
FTPFile[] files = ftp.listFiles();
for (FTPFile file : files) {
//判断是否是文件
if (file.isFile()) {
FtpFileInfo ftpFileInfo = new FtpFileInfo();
ftpFileInfo.setFileName(new String(file.getName().getBytes("iso-8859-1"),"GBK"));
ftpFileInfo.setFileSize(BigDecimal.valueOf(file.getSize()));
ftpFileInfo.setFileOwner(file.getGroup());
ftpFileInfo.setFilePath(pathName);
if(file.getType() == 0){
ftpFileInfo.setFileType("文件");
}else if(file.getType() == 1){
ftpFileInfo.setFileType("目录");
}
// ftpFileInfo.setFilePropertie(file.hasPermission());
ftpFileInfos.add(ftpFileInfo);
} else if (file.isDirectory()) {
FtpFileInfo ftpFileInfo = new FtpFileInfo();
ftpFileInfo.setFileName(file.getName());
ftpFileInfo.setFileSize(BigDecimal.valueOf(file.getSize()));
ftpFileInfo.setFileOwner(file.getUser());
ftpFileInfo.setFilePath(pathName);
if(file.getType() == 0){
ftpFileInfo.setFileType("文件");
}else if(file.getType() == 1){
ftpFileInfo.setFileType("目录");
}
// ftpFileInfo.setFilePropertie(file.hasPermission());
ftpFileInfos.add(ftpFileInfo);
}
}
}
return ftpFileInfos;
}
public static void main(String[] args) { try { FileInputStream in=new FileInputStream(new File("F:\\课件\\kubernetes技术\\CentOS7 部署K8S集群.docx")); boolean flag = uploadFile("192.168.175.129", 21, "lhf", "123456", "
/var/tmp","fileDirect", "CentOS7 部署K8S集群.docx", in); if(flag){ System.out.println("文件上传成功"); } boolean flag1= downloadFile("192.168.175.129", 21, "lhf", "123456", "/var/tmp/fileDirect","CentOS7 部署K8S集群.docx", "F:\\"); if(flag1){ System.out.println("文件下载成功"); } boolean flag2 = deleteFile ("192.168.175.129", 21, "lhf", "123456", "/var/tmp/fileDirect","CentOS7 部署K8S集群.docx"); if(flag){ System.out.println("删除成功"); } } catch (Exception e) { e.printStackTrace(); } } }
package com.ruoyi.system.domain;
import java.math.BigDecimal;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* ftp服务器文件对象 ftp_file_info
*
* @author lhf
* @date 2022-09-29
*/
public class FtpFileInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** 文件名 */
@Excel(name = "文件名")
private String fileName;
/** 文件大小 */
@Excel(name = "文件大小")
private BigDecimal fileSize;
/** 文件类型 */
@Excel(name = "文件类型")
private String fileType;
/** 文件属性 */
@Excel(name = "文件属性")
private String filePropertie;
/** 文件所属者 */
@Excel(name = "文件所属者")
private String fileOwner;
/** 文件路径 */
@Excel(name = "文件路径")
private String filePath;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setFileName(String fileName)
{
this.fileName = fileName;
}
public String getFileName()
{
return fileName;
}
public void setFileSize(BigDecimal fileSize)
{
this.fileSize = fileSize;
}
public BigDecimal getFileSize()
{
return fileSize;
}
public void setFileType(String fileType)
{
this.fileType = fileType;
}
public String getFileType()
{
return fileType;
}
public void setFilePropertie(String filePropertie)
{
this.filePropertie = filePropertie;
}
public String getFilePropertie()
{
return filePropertie;
}
public void setFileOwner(String fileOwner)
{
this.fileOwner = fileOwner;
}
public String getFileOwner()
{
return fileOwner;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("fileName", getFileName())
.append("fileSize", getFileSize())
.append("fileType", getFileType())
.append("updateTime", getUpdateTime())
.append("filePropertie", getFilePropertie())
.append("fileOwner", getFileOwner())
.append("filePath", getFilePath())
.toString();
}
}