查找指定文件工具类

在工作中,需要查找文件夹中指定文件,进行遍历,写了关于File的工具类

package com.cykj.reports.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 关于File操作的工具类:
 * 1.解析url,遍历 File,查找指定文件
 * 2.上传文件夹,将 MultipartFile 转为 File,遍历File,查找指定文件
 * 3.删除文件夹或文件
 *
 * 查找指定文件:
 *    在指定路径或目录下:查找指定的文件(根据关键字或正则表达式)
 * 三种方式
 * 方式一:运用 listFiles() 返回 fileList 查找 ,用时最短
 * 方式二:应用 listFiles() 返回 list、fileList、directorList 查找 ,用时中等
 * 方式三:运用 listFiles(new FileFilter())内部类 查找 ,用时最长
 *
 * 文件夹上传:
 * MultipartFile文件上传
 *  单文件: MultipartFile file
 *  多文件:(定义为数组形式)MultipartFile[] file
 *  判断文件是否为空: !file.isEmpty() – 不为空
 *  获取上传的文件的名称: file.getOriginalFilename();
 *  转存文件: file.transferTo(new File(filePath));
 *
 * @author ligong.zhang
 */
@Slf4j
public class SearchFileUtil {
//    private Logger logger = LoggerFactory.getLogger(SearchFileUtil.class);

    private List<File> fileList = new ArrayList<>();    // 存放文件
    private List<File> directoryList = new ArrayList<>();   // 存放目录
    private List<File> list = new ArrayList<>();    // 存放文件和目录

    private String regex;   // 正则表达式或普通字符串
    private int countFiles = 0;  // 声明统计文件个数的变量
    private int countFolders = 0;    // 声明统计文件夹的变量

    public SearchFileUtil(String regex) {    //根据file和regex初始化
        this.regex = regex;
    }


    /**
     * 方式一:根据file查找指定文件
     * @time 用时最短
     * @count countFiles / countFolders
     * @condition startsWith() / endsWith() / contains() / indexOf() / matches(String regex)
     * @param file
     * @return fileList
     */
    public List<File> findFile(File file){

        File[] files = file.listFiles();    //列出所有文件集合
        for (File f : files) {
            if (f.isDirectory()) {  //判断是否是文件夹
                countFolders++;     //文件夹计数
                findFile(f);   //递归
            }else {
                countFiles++;   //文件计数
                if (f.getName().endsWith(regex)) {    //判断文件是否是指定文件
                    fileList.add(f);    //保存文件到集合
                }
            }
        }

        return fileList;
    }


    /**
     * 方式二:递归搜索当前目录下的所有文件及目录
     * @time 用时中等
     * @count countFiles / countFolders
     * @condition startsWith() / endsWith() / contains() / indexOf() / matches(String regex)
     * @param file
     * @return list / fileList / directoryList
     */
    public List<File> findFile2(File file) {
        File[] files = file.listFiles();
        if (files == null || files.length == 0)
            return null;
        for (File f : files) {    //matches(regex):String里去匹配正则表达式,相当于是否包含满足规则的子字符串
            if (f.getName().endsWith(regex)){
                list.add(f);    //list保存满足条件的文件或文件夹
            }
            if (f.isDirectory()){
                countFolders++;     //文件夹计数
                if (f.getName().endsWith(regex)) {
                    directoryList.add(f);   //保存到文件夹集合
                }
                findFile2(f);   //递归调用
            } else {
                countFiles++;   //文件计数
                if (f.getName().endsWith(regex)) {
                    fileList.add(f);    //保存到文件集合
                }
            }
        }
        return fileList;
    }


    /**
     * 方式三:根据文件和关键字查询指定文件并返回文件的数组
     * @time 用时最长
     * @count countFiles / countFolders
     * @condition startsWith() / endsWith() / contains() / indexOf() / matches(String regex)
     * @param file
     * @return fileList
     */
    public List<File> findFile3(File file) {// 递归查找包含关键字的文件

        //相当于遍历当前文件夹,满足条件的返回(不涉及子文件夹)
        File[] files = file.listFiles(new FileFilter() {// 运用内部匿名类获得文件
            @Override
            public boolean accept(File f) {     // 实现FileFilter类的accept方法
                if (f.isFile())     // 如果是文件
                    countFiles++;
                else
                    countFolders++;     // 如果是目录
                if (f.isDirectory() || (f.isFile() &&      //包含时用contains(String keyword)
                        f.getName().toLowerCase().endsWith(regex.toLowerCase())))// 目录或文件包含关键字
                    return true;
                return false;
            }
        });

        //遍历满足条件的文件数组
        for (int i = 0; i < files.length; i++) {// 循环显示文件夹或文件
            if (files[i].isFile()) {// 如果是文件则将文件添加到结果列表中
                fileList.add(files[i]);
            } else {// 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中
                findFile3(files[i]);
            }
        }

//        File[] result = new File[fileList.size()];// 声明文件数组,长度为集合的长度
//        fileList.toArray(result);// 集合数组化
        return fileList;
    }


    /**
     * 文件夹上传:将MultipartFile转为File,再遍历File
     * StandardMultipartFile 不能强转为 CommonsMultipartFile
     * 1.在项目中添加一个配置类,注册CommonsMultipartResolver
     * 2.如果是springboot项目在application.properties中加入multipart.enabled=true
     * @param folder
     * @param request
     * @return fileList
     */
    public List<File> findFile4(MultipartFile[] folder, HttpServletRequest request) {

        if (folder != null && folder.length>0) {
            for (MultipartFile mf : folder) {
                countFiles++;   //计算查找的文件数量
                try {
                    //在根目录下创建一个tempfileDir的临时文件夹
                    String contextpath = request.getContextPath() + File.separator + "tempfileDir";
                    File file = new File(contextpath);
                    if(!file.exists()){
                        file.mkdirs();
                    }       // mf.getName()   // 为上传的key值
                    //在tempfileDir的临时文件夹下创建一个新的和上传文件名一样的文件
                    String filepath = contextpath + File.separator + getRandomData() + mf.getOriginalFilename(); // 上传的真实文件的文件名

                    //判断文件是否满足规范
                    if (filepath.endsWith(regex)) {
                        File newFile = new File(filepath);
                        //也可以不用去将mf转化为CommonsMultipartFile
//                        CommonsMultipartFile commonsmultipartfile = (CommonsMultipartFile) mf;
                        mf.transferTo(newFile);
                        fileList.add(newFile);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }


        //方法2:不生成临时文件,直接转换
        /*int fileSize = folder.length;
        File[] files = new File[fileSize];
        for (int i = 0; i < folder.length; i++) {
            CommonsMultipartFile f = (CommonsMultipartFile) folder[i];
            DiskFileItem dfi = (DiskFileItem) f.getFileItem();
            File tempFile = dfi.getStoreLocation();
            files[i] = tempFile;
        }

        for (File file : files) {
            System.out.println(file.getName());
        }*/

        return fileList;
    }


    /**
     * 删除文件夹或文件
     * @return
     */
    public void deleteFile(File file){
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                deleteFile(f);
            }
            f.delete();
        }
    }


    /**
     * 获取随机的一个12位数字
     * @return
     */
    private StringBuffer getRandomData(){

        String sources = "0123456789"; // 加上一些字母,就可以生成pc站的验证码了
        Random rand = new Random();
        StringBuffer flag = new StringBuffer();
        for (int j = 0; j < 12; j++) {
            //nextInt() 在方法调用返回介于0(含)和n(不含)伪随机,均匀分布的int值。
            flag.append(sources.charAt(rand.nextInt(10)) + "");
        }

        return flag;
    }




    //用主函数进行测试
    public static void main(String[] args) {
        File file = new File("//10.150.15.20/Transsionsharing/研发一部软件测试部/GMS测试结果(勿删)/CC7/CC7-H626ABC-P-190806V145");
        if (!file.exists()) {
            System.out.println("目录不存在:" + file.getAbsolutePath());
            return;
        }
        SearchFileUtil sfu = new SearchFileUtil(".xml");
        List<File> fileList = sfu.findFile(file);  //查找指定文件

        //打印输出
        System.out.println("在 " + file.getName() + " 文件夹以及所有子文件夹里查找 .xml 文件");
        System.out.println("查找了" + sfu.getCountFiles() + " 个文件," + sfu.getCountFolders() + " 个文件夹,共找到 " + fileList.size() + " 个符合条件的文件:");
        for (File f : fileList) {
            System.out.println(f.getAbsolutePath());
        }

        return;
    }


    public int getCountFiles() {
        return countFiles;
    }

    public void setCountFiles(int countFiles) {
        this.countFiles = countFiles;
    }

    public int getCountFolders() {
        return countFolders;
    }

    public void setCountFolders(int countFolders) {
        this.countFolders = countFolders;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用说明 : 1、本程序可以作什么? 本程序功能分为两个部分: 一部分是:批量查找指定路径下的文件中的内容中,是否包含要查询的项目。并把查询出的内容分文件存储。 一部分是:将文本文件导入EXCEL中,可以将上一步查找的结果导入,也可以自己选择文件导入(支持多选)。 2、如何使用他? a、批量查找: 首先,在“读入位置”按钮处设置你所要读取的文件的存放位置,此时程序会自动读入此文件夹下所有文件,以供选择;其次,用“>>”或“>”将要读取的文件选入读取队列,当然如果选错了可以用“<<”或“<”删除队列,或者鼠标双击选中项删除;再次,点击“+”按钮,添加查找项目到查找项目列表,一次只可以添加一条,如需添加多条则需要重复添加操作;如果添加错误可以双击选中项删除或选中后点击“-”按钮。最后,点击“开始查找”,程序将会把查找结果输出保存到指定路径下面的output文件夹下面,你可以选择是否打开目录查看。如果需要查询文件文件头,可以选择“保留文件首行”。 b、EXCEL导入: 首先,选择导入方式,导入方式分为“查询结果导入”和“新选文件导入”两种;当选择“查询结果导入”时,本程序将把“读入位置”处“output”文件夹下文件批量导入EXCEL。当选择“新选文件导入”时,本程序在点击“开始导入”时将弹出窗口,您可以自己选择需要导入文件(支持多选),导入EXCEL。其次,设置导入文件时的分割符,默认为“|”,本程序只支持按照分隔符导入。最后,点击“开始导入”按钮开始导入。 3、本程序不判断所查找文件类型 由于本程序在读入文件时,并没有校验文件的内容和文件类型,因此本程序会读取用户所选择的任意文件,即使此文件是二进制格式的。不论是查询或者是导入功能都是这样。本程序将按行读取所选择的文件(或者有换行符的),在读取完文件后,无论是否找到,都会创建和源文件相同类型的文件,即使是.exe或.rar(一般是打不开的),文件名存储为“output”+原文件名。即使没有找到任何相匹配的内容,本程序也会创建文件,这时后文件大小是0字节,可以按照大小排列看到。 4、请使用“清除文件”按钮及时清除查询结果 程序在查询和创建文件的过程中,不会判断是否已经执行过查询操作。如果已经执行过查询操作,“output”文件夹下就会存在查询出的文件,当再次执行查询时,本程序会在已存在的文件后追加查询结果。这样就会出现重复的记录或内容。因此,当需要多次查询时,每次查询前需要点击“清空文件”按钮删除output文件夹,才能保证查找的准确。 5、本程序不会判断运行的环境,因此在运行过程中可能会有些未知的错误 本程序在win7环境,vs2012,Netframe4.0下编译通过。本程序支持winxp及以上操作系统。执行EXCEL导入的时候,需要安装Office。Office的版本在2003以上就可以。但是不同我Office版本对导入性能,有一定的影响。Excel2003,最多256列,即2的8次方,最多65536行,即2放入16次方; Excel2007及以上版本,最多16384列,即2的14次方,最多1048576行,即2的20次方。因此如果需要导入的单个文件的行数或者列数,超过了所安装Office版本的最多行列数,程序将会报错!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值