java实现从FTP服务器上遍历目录

tech2023-02-28  108

package com.fhresource.common.util; import com.fhresource.common.constants.Constants; import com.fhresource.common.entity.bo.FileAttribute; import com.fhresource.common.entity.vo.Result; import com.fhresource.common.ftp.FTPConstant; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.net.PrintCommandListener; 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.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Logger; import java.util.stream.Collectors; /** * * @Author lzy */ public class FTPListAllFiles { private static Logger logger = Logger.getLogger(String.valueOf(FTPListAllFiles.class)); private FTPConstant ftpConstant; public FTPClient ftp; public ArrayList<String> arFiles; public FTPListAllFiles(boolean isPrintCommmand) { ftp = new FTPClient(); arFiles = new ArrayList<String>(); if (isPrintCommmand) { ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); } } /** * 登陆FTP服务器 * * @param host FTPServer IP地址 * @param port FTPServer 端口 * @param username FTPServer 登陆用户名 * @param password FTPServer 登陆密码 * @return 是否登录成功 * @throws IOException */ public boolean login(String host, int port, String username, String password) throws IOException { this.ftp.connect(host, port); if (FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) { if (this.ftp.login(username, password)) { /** 需要注意这句代码,如果调用List()方法出现,文件的无线递归,与真实目录结构不一致的时候,可能就是因为转码后,读出来的文件夹与正式文件夹字符编码不一致所导致。 则需去掉转码,尽管递归是出现乱码,但读出的文件就是真实的文件,不会死掉。等读完之后再根据情况进行转码。 如果ftp部署在windows下,则: */ this.ftp.setControlEncoding("UTF-8"); return true; } } if (this.ftp.isConnected()) { this.ftp.disconnect(); } return false; } /** * 关闭数据链接 * * @throws IOException */ public void disConnection() throws IOException { if (this.ftp.isConnected()) { this.ftp.disconnect(); } } public List<FileAttribute> setFileAttributeList(List<FileAttribute> fileAttributeList, FileAttribute fileAttribute, FTPFile file, String filePath){ fileAttribute.setFileName(file.getName()); fileAttribute.setFilePath(filePath+file.getName()); fileAttribute.setFileSize(file.getSize()); fileAttributeList.add(fileAttribute); return fileAttributeList; } /** * 递归遍历出目录下面所有文件 * * @param pathName 需要遍历的目录,必须以"/"开始和结束 * @throws IOException */ public void List(String pathName, List<FileAttribute> fileAttributeList,Integer parentId,Integer id) throws IOException { if (pathName.startsWith("/") && pathName.endsWith("/")) { //更换目录到当前目录 //this.ftp.changeWorkingDirectory(new String(pathName.getBytes(), FTP.DEFAULT_CONTROL_ENCODING)); this.ftp.changeWorkingDirectory(new String(pathName.getBytes(), StandardCharsets.ISO_8859_1)); FTPFile[] files = this.ftp.listFiles(); List<FileAttribute> dirfileAttributeList =new ArrayList<>(); for (FTPFile file : files) { FileAttribute fileAttribute=new FileAttribute(); fileAttribute.setParentId(parentId); //判断是否是文件 if (file.isFile()) { fileAttribute.setIsfile(Constants.FTP_FILE); //组装文件类 setFileAttributeList(fileAttributeList,fileAttribute,file,pathName); } else if (file.isDirectory()) { id++; fileAttribute.setFileSize(file.getSize()); fileAttribute.setFileId(id); fileAttribute.setFileName(file.getName()); fileAttribute.setIsfile(Constants.FTP_FOLDER); fileAttribute.setFilePath(pathName+file.getName()); fileAttributeList.add(fileAttribute); dirfileAttributeList.add(fileAttribute); } } if (dirfileAttributeList!=null&&dirfileAttributeList.size()>0){ for ( FileAttribute fileAttribute :dirfileAttributeList){ //save(fileAttribute);保存数据库返回主键id parentId=fileAttribute.getFileId(); // 需要加此判断。否则,ftp默认将‘项目文件所在目录之下的目录(./)’与‘项目文件所在目录向上一级目录下的目录(../)’都纳入递归,这样下去就陷入一个死循环了。需将其过滤掉。 if (!".".equals(fileAttribute.getFileName()) && !"..".equals(fileAttribute.getFileName())) { List(pathName + fileAttribute.getFileName() + "/",fileAttributeList,parentId,id); } } } } } /** * 递归遍历目录下面指定的文件名 * * @param pathName 需要遍历的目录,必须以"/"开始和结束 * @param ext 文件的扩展名 * @throws IOException */ public void List(String pathName, String ext) throws IOException { if (pathName.startsWith("/") && pathName.endsWith("/")) { //更换目录到当前目录 this.ftp.changeWorkingDirectory(new String(pathName.getBytes(), StandardCharsets.ISO_8859_1)); //this.ftp.changeWorkingDirectory(new String(pathName.getBytes(), FTP.DEFAULT_CONTROL_ENCODING) ); FTPFile[] files = this.ftp.listFiles(); for (FTPFile file : files) { if (file.isFile()) { if (file.getName().endsWith(ext)) { arFiles.add(pathName + file.getName()); } } else if (file.isDirectory()) { if (!".".equals(file.getName()) && !"..".equals(file.getName())) { List(pathName + file.getName() + "/", ext); } } } } } public static Result testHello() throws IOException { FTPListAllFiles f = new FTPListAllFiles(true); List<FileAttribute> fileAttributeList=new ArrayList<FileAttribute>(); FileAttribute file = new FileAttribute(); file.setIsfile(Constants.FTP_FOLDER); file.setFileId(Constants.ONE); file.setParentId(Constants.ZERO); file.setFileName("** **"); file.setFilePath("/zhzyk"); fileAttributeList.add(file); Integer parentId=Constants.ONE; Integer id=Constants.TWO; if (f.login("ip", 21, "用户名","密码")) { f.List("/mnt/data2/110ftp/zhzyk/", fileAttributeList, parentId, id); } f.disConnection(); List<FileAttribute> roots = fileAttributeList.stream().filter(groupCategory -> (groupCategory.getParentId().equals(0))).collect(Collectors.toList()); List<FileAttribute> subs = fileAttributeList.stream().filter(groupCategory -> (groupCategory.getParentId() != 0)).collect(Collectors.toList()); roots.forEach(root -> buildSubs(root, subs)); return Result.success(roots); } /** * 递归构建 * @param parent * @param subs */ private static void buildSubs(FileAttribute parent, List<FileAttribute> subs) { List<FileAttribute> children = subs.stream().filter(sub -> (sub.getParentId() .equals(parent.getFileId()) )).collect(Collectors.toList()); //有子分类的情况 if (!CollectionUtils.isEmpty(children)) { parent.setListenerList(children); //再次递归构建 children.forEach(child -> buildSubs(child, subs)); } } }

不懂的可以问我,一起学习。

最新回复(0)