Analyse de fichiers Java et recherche de chaînes dans plusieurs fichiers

avant-propos

Si vous souhaitez analyser quels fichiers se trouvent dans un répertoire (y compris les sous-répertoires); ou si vous souhaitez rechercher le contenu de tous les fichiers d'un dossier, quelles lignes de quels fichiers contiennent le mot-clé "xxx", cet article peut vous aider.

1. Outils



import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class SearchWord {
    
    

   //当在文件夹中搜索时,遇到以下非文本文件则跳过
    public static List<String> excludeFileType = Arrays.asList(
            "jar", "zip", "rar", "7z", "tar", "gz", "xz", "bz2", "doc", "class", "pak",
            "xls", "ppt", "pdf", "docx", "xlsx", "pptx", "jpg", "jpge", "gif", "png",
            "xltd", "war", "hprof", "m4a", "swf", "mobi", "jpeg", "tiff", "svg", "psd",
            "mp3", "aac", "mp4", "avi", "flv", "mkv", "mpeg", "msi", "tgz", "mdf",
            "rmvb", "apk", "ts", "map", "car", "mov", "wav", "raw", "dll", "woff",
            "eot", "otf", "ico", "ttf", "ttc", "fon", "dl_", "pd_", "ex_", "etl",
            "sys", "iso", "isz", "esd", "wim", "gho", "dmg", "mpf", "exe", "ldf");

    /**
     * 搜索指定文件中的关键字
     *
     * @param filePath  要搜索的文件路径
     * @param searchStr 要搜索的关键字
     * @return 返回的 map<行数, 该行内容>
     */
    public static Map<Integer, String> scanFile(String filePath, String searchStr) {
    
    
        Map<Integer, String> map = new LinkedHashMap<>();
        FileInputStream file = null; //读取文件为字节流
        try {
    
    
            file = new FileInputStream(filePath);
            InputStreamReader in = new InputStreamReader(file, StandardCharsets.UTF_8); //字节流转化为字符流,以GBK读取防止中文乱码
            BufferedReader buf = new BufferedReader(in); //加入到缓存区
            String str = "";
            int row = 1;
            while ((str = buf.readLine()) != null) {
    
     //按行读取,到达最后一行返回null
                if (str.contains(searchStr)) {
    
    
                    map.put(row, str);
                }
                row++;
            }
            buf.close();
            file.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 扫描dirPath下所有文件
     *
     * @param dirPath 要搜索的文件夹路径
     * @return 返回所有文件的路径
     */
    public static List<String> getAllFilesPath(String dirPath) {
    
    
        List<String> list = new ArrayList<>();
        return getAll_FilesPath(dirPath, list);
    }

    /**
     * 扫描dirPath下所有文件
     *
     * @param dirPath    要搜索的文件夹路径
     * @param excludeDir 不扫描的文件夹名列表
     * @return 返回所有文件的路径
     */
    public static List<String> getAllFilesPathEx(String dirPath, List<String> excludeDir) {
    
    
        List<String> list = new ArrayList<>();
        return getAll_FilesPath(dirPath, list, excludeDir);
    }

    /**
     * 扫描dirPath下的所有文件类型是fileType的文件
     *
     * @param dirPath  要搜索的文件夹路径
     * @param fileType 文件后缀,要扫描的文件的类型
     * @return 返回所有fileType类型文件的路径
     */
    public static List<String> getAllFilesPath(String dirPath, List<String> fileType) {
    
    
        List<String> list = new ArrayList<>();
        return getAllFiles(dirPath, fileType, list);
    }

    /**
     * 扫描dirPath下的所有文件类型是fileType的文件
     *
     * @param dirPath    要搜索的文件夹路径
     * @param fileType   文件后缀,要扫描的文件的类型
     * @param excludeDir 不扫描的文件夹名列表
     * @return 返回所有fileType类型文件的路径
     */
    public static List<String> getAllFilesPath(String dirPath, List<String> fileType, List<String> excludeDir) {
    
    
        List<String> list = new ArrayList<>();
        return getAllFiles(dirPath, fileType, list, excludeDir);
    }

    /**
     * @param dirPath   要搜索的文件夹路径
     * @param searchStr 要搜索的关键字
     * @param fileType  要搜索的文件后缀
     * @return <文件名, <行数, 该行内容>>
     */
    public static Map<String, Map<Integer, String>> searchFiles(String dirPath, String searchStr, List<String> fileType) {
    
    
        return searchFiles(dirPath, searchStr, fileType, null);
    }

    /**
     * @param dirPath    要搜索的文件夹路径
     * @param searchStr  要搜索的关键字
     * @param fileType   要搜索的文件后缀
     * @param excludeDir 不扫描的文件夹名列表
     * @return <文件名, <行数, 该行内容>>
     */
    public static Map<String, Map<Integer, String>> searchFiles(String dirPath, String searchStr, List<String> fileType, List<String> excludeDir) {
    
    
        List<String> allFiles = excludeDir == null || excludeDir.size() == 0 ? getAllFilesPath(dirPath, fileType) : getAllFilesPath(dirPath, fileType, excludeDir);
        Map<String, Map<Integer, String>> searchInfo = new LinkedHashMap<>();
        for (String f : allFiles) {
    
    
            System.out.println("正在文件中搜索,当前搜索文件:" + f);
            Map<Integer, String> map = scanFile(f, searchStr);
            if (map.size() != 0) {
    
    
                searchInfo.put(f, map);
            }
        }
        return searchInfo;
    }


    /**
     * 搜索文件夹下所有可读文件中是否含有要查找的关键字
     *
     * @param dirPath   要搜索的文件夹路径
     * @param searchStr 要搜索的关键字
     * @return <文件名, <行数, 该行内容>>
     */
    public static Map<String, Map<Integer, String>> searchAllFiles(String dirPath, String searchStr) {
    
    
        return searchAllFiles(dirPath, searchStr, null);
    }

    /**
     * 搜索文件夹下所有可读文件中是否含有要查找的关键字
     *
     * @param dirPath    要搜索的文件夹路径
     * @param searchStr  要搜索的关键字
     * @param excludeDir 不扫描的文件夹名列表
     * @return <文件名, <行数, 该行内容>>
     */
    public static Map<String, Map<Integer, String>> searchAllFiles(String dirPath, String searchStr, List<String> excludeDir) {
    
    
        List<String> allFiles = excludeDir == null || excludeDir.size() == 0 ? getAllReadFilessPath(dirPath, new ArrayList<>(), null) : getAllReadFilessPath(dirPath, new ArrayList<>(), excludeDir);
        Map<String, Map<Integer, String>> searchInfo = new LinkedHashMap<>();
        for (String f : allFiles) {
    
    
            System.out.println("正在文件中搜索,当前搜索文件:" + f);
            Map<Integer, String> map = scanFile(f, searchStr);
            if (map.size() != 0) {
    
    
                searchInfo.put(f, map);
            }
        }
        return searchInfo;
    }

    /**
     * @param dirPath   要搜索的文件夹路径
     * @param searchStr 要搜索的关键字
     * @param fileType  要搜索的文件后缀
     * @return <文件名, <行数, 该行内容>>
     */
    public static void searchAndPrint(String dirPath, String searchStr, List<String> fileType) {
    
    
        Map<String, Map<Integer, String>> map = SearchWord.searchFiles(dirPath, searchStr, fileType);
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

    //获取所有的文件路径,excludeDir是要跳过查询的文件夹名列表
    public static List<String> getAllReadFilessPath(String dirPath, List<String> list, List<String> excludeDir) {
    
    
        File file = new File(dirPath);
        File[] tempList = file.listFiles();
        System.out.println("正在扫描文件夹:" + dirPath);
        if (null != tempList) {
    
    
            for (int i = 0; i < tempList.length; i++) {
    
    
                String filePath = tempList[i].toString();
                String file_Type = filePath.substring(filePath.lastIndexOf(".") + 1);
                if (tempList[i].isFile()) {
    
    
                    //如果是可读的文本文件
                    if (!excludeFileType.contains(file_Type)) {
    
    
                        list.add(filePath);
                    }
                } else {
    
    
                    if (excludeDir == null || excludeDir.size() == 0) {
    
    
                        getAllReadFilessPath(filePath, list, excludeDir);
                    } else {
    
    
                        String dirName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
                        if (!excludeDir.contains(dirName)) {
    
    
                            //如果是文件夹则递归
                            getAllReadFilessPath(filePath, list, excludeDir);
                        }
                    }
                }
            }
        }
        return list;
    }

    //获取文件夹下所有的文件路径,excludeDir是要跳过查询的文件夹名列表
    public static List<String> getAll_FilesPath(String dirPath, List<String> list, List<String> excludeDir) {
    
    
        File file = new File(dirPath);
        File[] tempList = file.listFiles();
        System.out.println("正在扫描文件夹:" + dirPath);
        if (null != tempList) {
    
    
            for (int i = 0; i < tempList.length; i++) {
    
    
                String filePath = tempList[i].toString();
                if (tempList[i].isFile()) {
    
    
                    list.add(filePath);
                } else {
    
    
                    //如果是文件夹则递归
                    if (excludeDir == null || excludeDir.size() == 0) {
    
    
                        getAll_FilesPath(filePath, list);
                    } else {
    
    
                        String dirName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
                        if (!excludeDir.contains(dirName)) {
    
    
                            //如果是文件夹则递归
                            getAll_FilesPath(filePath, list, excludeDir);
                        }
                    }
                }
            }
        }
        return list;
    }

    //获取文件夹下所有的文件路径
    public static List<String> getAll_FilesPath(String path, List<String> list) {
    
    
        return getAll_FilesPath(path, list, null);
    }

    //获取所有的文件路径,fileType是所有要查询的文件类型
    public static List<String> getAllFiles(String dirPath, List<String> fileType, List<String> list) {
    
    
        return getAllFiles(dirPath, fileType, list, null);
    }

    //获取所有的文件路径,fileType是所有要查询的文件类型,excludeDir是要跳过查询的文件夹名列表
    public static List<String> getAllFiles(String dirPath, List<String> fileType, List<String> list, List<String> excludeDir) {
    
    
        File file = new File(dirPath);
        File[] tempList = file.listFiles();
        System.out.println("正在扫描文件夹:" + dirPath);
        if (null != tempList) {
    
    
            for (int i = 0; i < tempList.length; i++) {
    
    
                String filePath = tempList[i].toString();
                String file_Type = filePath.substring(filePath.lastIndexOf(".") + 1);
                if (tempList[i].isFile()) {
    
    
                    //如果是文件
                    if (fileType.contains(file_Type)) {
    
    
                        list.add(filePath);
                    }
                } else {
    
    
                    if (excludeDir == null || excludeDir.size() == 0) {
    
    
                        getAllFiles(filePath, fileType, list);
                    } else {
    
    
                        String dirName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
                        if (!excludeDir.contains(dirName)) {
    
    
                            //如果是文件夹则递归
                            getAllFiles(filePath, fileType, list, excludeDir);
                        }
                    }
                }
            }
        }
        return list;
    }
}



2. Analysez tous les fichiers du dossier

​ Scannez tous les fichiers dans D:\Xunlei Download\folder

    public static void main(String[] args) {
    
    
        String dir = "D:\\迅雷下载\\";
        List<String> filesPath = SearchWord.getAllFilesPath(dir);
        filesPath.forEach(System.out::println);
    }

sortir:

D:\迅雷下载\1623720138.rar
D:\迅雷下载\codeNotes-master.zip
D:\迅雷下载\DittoSetup_64bit_3_24_184_0.exe
D:\迅雷下载\eclipse-inst-jre-win64.exe
D:\迅雷下载\eclipse-jee-2021-09-R-win32-x86_64.zip
D:\迅雷下载\fastjson-1.2.76.jar
D:\迅雷下载\guava-30.1.1-jre.jar
D:\迅雷下载\ideaIU-213.5605.12.exe
D:\迅雷下载\imageglass_8.2.6.6_x64.msi
D:\迅雷下载\latest-win64.zip.xltd
D:\迅雷下载\latest-win64.zip.xltd.cfg
D:\迅雷下载\layDate-v5.3.1\laydate\laydate.js
D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font\iconfont.woff
D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\laydate.css
D:\迅雷下载\layDate-v5.3.1\test.html
D:\迅雷下载\layDate-v5.3.1\文档\文档.url
D:\迅雷下载\layDate-v5.3.1\更新日志.url
D:\迅雷下载\layDate-v5.3.1.zip
D:\迅雷下载\springboot-demo-maven-master.zip
D:\迅雷下载\yx12345sqlyog.rar
D:\迅雷下载\新建文件夹\ideaIU-2021.1.1.exe
D:\迅雷下载\新建文件夹\note.txt

3. Analysez tous les fichiers sous le dossier, excluez le dossier spécifié

Scannez tous les fichiers sous le dossier D:\Xunlei Download\, ne scannez pas les fichiers sous le dossier "layDate-v5.3.1"

    public static void main(String[] args) {
    
    
        String dir = "D:\\迅雷下载\\";
        List<String> excludeDir = Arrays.asList("layDate-v5.3.1");
        List<String> filesPath = SearchWord.getAllFilesPathEx(dir,excludeDir);
        filesPath.forEach(System.out::println);
    }

sortir:

D:\迅雷下载\1623720138.rar
D:\迅雷下载\codeNotes-master.zip
D:\迅雷下载\DittoSetup_64bit_3_24_184_0.exe
D:\迅雷下载\eclipse-inst-jre-win64.exe
D:\迅雷下载\eclipse-jee-2021-09-R-win32-x86_64.zip
D:\迅雷下载\fastjson-1.2.76.jar
D:\迅雷下载\guava-30.1.1-jre.jar
D:\迅雷下载\ideaIU-213.5605.12.exe
D:\迅雷下载\imageglass_8.2.6.6_x64.msi
D:\迅雷下载\latest-win64.zip.xltd
D:\迅雷下载\latest-win64.zip.xltd.cfg
D:\迅雷下载\layDate-v5.3.1.zip
D:\迅雷下载\springboot-demo-maven-master.zip
D:\迅雷下载\yx12345sqlyog.rar
D:\迅雷下载\新建文件夹\ideaIU-2021.1.1.exe
D:\迅雷下载\新建文件夹\note.txt

4. Analysez le type de fichiers spécifié dans le dossier

Scannez D:\Xunlei Download\dossier pour les fichiers jar, zip, txt

    public static void main(String[] args) {
    
            
        String dir = "D:\\迅雷下载\\";
        List<String> filesType = Arrays.asList("jar","zip","txt");
        List<String> filesPath = SearchWord.getAllFilesPath(dir,filesType);
        filesPath.forEach(System.out::println);
     }

sortir:

D:\迅雷下载\codeNotes-master.zip
D:\迅雷下载\eclipse-jee-2021-09-R-win32-x86_64.zip
D:\迅雷下载\fastjson-1.2.76.jar
D:\迅雷下载\guava-30.1.1-jre.jar
D:\迅雷下载\layDate-v5.3.1.zip
D:\迅雷下载\springboot-demo-maven-master.zip
D:\迅雷下载\新建文件夹\note.txt

5. Analysez le type de fichiers spécifié sous le dossier et excluez le dossier spécifié

Analysez le dossier D:\Xunlei Download\ pour les fichiers jar, zip et txt. S'il existe un dossier nommé "Nouveau dossier", le fichier sous ce dossier ne sera pas analysé

    public static void main(String[] args) {
    
            
        String dir = "D:\\迅雷下载\\";
        List<String> filesType = Arrays.asList("jar","zip","txt");
        List<String> excludeDir = Arrays.asList("新建文件夹");
        List<String> filesPath = SearchWord.getAllFilesPath(dir,filesType,excludeDir);
        filesPath.forEach(System.out::println);
     }

sortir:

D:\迅雷下载\codeNotes-master.zip
D:\迅雷下载\eclipse-jee-2021-09-R-win32-x86_64.zip
D:\迅雷下载\fastjson-1.2.76.jar
D:\迅雷下载\guava-30.1.1-jre.jar
D:\迅雷下载\layDate-v5.3.1.zip
D:\迅雷下载\springboot-demo-maven-master.zip

6. Rechercher une chaîne dans le fichier spécifié

​ Recherchez le mot-clé insertData dans le fichier server.log

    public static void main(String[] args) {
    
            
        String filePath = "D:\\迅雷下载\\server.log";
        String searchWord = "insertData";
        Map<Integer, String> map = SearchWord.scanFile(filePath,searchWord);
        for(Map.Entry<Integer, String> entry : map.entrySet()){
    
    
            System.out.println("第"+entry.getKey()+"行:"+entry.getValue());
        }
     }

sortir:

67:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-开始插入数据库list大小:368:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:4269:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-handleResult结束
第70:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-firm大小:15

7. Rechercher des chaînes dans des fichiers d'un type spécifié sous un dossier

Trouvez le mot-clé insertData dans tous les fichiers de type "txt", "log" sous D:\Xunlei Download\

    public static void main(String[] args) {
    
       
	    String dir = "D:\\迅雷下载\\";
        String searchStr = "insertData";
        List<String> fileType = Arrays.asList("txt", "log");
        Map<String, Map<Integer, String>> map = SearchWord.searchFiles(dir, searchStr, fileType);
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

ou

    public static void main(String[] args) {
    
       
		SearchWord.searchAndPrint(dir,searchStr,fileType);
    }

sortir:

文件路径: D:\迅雷下载\server.log
第67:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-开始插入数据库list大小:368:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:4269:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-handleResult结束
第70:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-firm大小:15
    
文件路径: D:\迅雷下载\新建文件夹\note.txt
第15行:insertData-插入数据库
第17行:insertData-fserviceid:21-1419行:insertData-firmpv:120行:insertData-firmuv:121行:insertData-userpv:122行:insertData-useruv:1

8. Rechercher des chaînes dans des fichiers d'un type spécifié sous un dossier, à l'exclusion des dossiers spécifiés

Rechercher le mot-clé insertData dans tous les fichiers de type "txt", "log" sous le dossier D:\Xunlei Download\, si le nom du dossier est "Nouveau dossier", exclure la recherche de ce dossier

    public static void main(String[] args) {
    
       
	    String dir = "D:\\迅雷下载\\";
        String searchStr = "insertData";
        List<String> fileType = Arrays.asList("txt", "log");
        List<String> excludeDir = Arrays.asList("新建文件夹"); //遇到文件夹名为"新建文件夹"则跳过该文件夹
        Map<String, Map<Integer, String>> map = SearchWord.searchFiles(dir, searchStr, fileType, excludeDir);
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

sortir:

文件路径: D:\迅雷下载\server.log
第67:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-开始插入数据库list大小:368:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:4269:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-handleResult结束
第70:[http-nio-8080-exec-339  2021 Dec 27 15:10:42]insertData-firm大小:15

9. Rechercher une chaîne dans tous les fichiers lisibles du dossier spécifié

Recherchez le mot-clé ssssss dans tous les fichiers texte sous le dossier D:\Xunlei Download\. Par défaut, les fichiers non textuels tels que la musique et la vidéo ne seront pas recherchés

    public static void main(String[] args) throws IOException {
    
    
 		String dir = "D:\\迅雷下载\\";
        String searchStr ="ssssss";
        Map<String, Map<Integer, String>> map = SearchWord.searchAllFiles(dir, searchStr);
        System.out.println("");
        System.out.println("--------------------------------------------------------");
        System.out.println("搜索完成,结果:");
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

sortir:

正在扫描文件夹:D:\迅雷下载\
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\laydate
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\laydate\theme
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\文档
正在扫描文件夹:D:\迅雷下载\test
正在扫描文件夹:D:\迅雷下载\新建文件夹
正在文件中搜索,当前搜索文件:D:\迅雷下载\aaa
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font\iconfont.eot
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font\iconfont.woff
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\laydate.css
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\test.html
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\文档\官网.url


--------------------------------------------------------
搜索完成,结果:
文件路径: D:\迅雷下载\aaa
第1行:ssssss

10. Rechercher des chaînes dans tous les fichiers lisibles sous le dossier spécifié, à l'exclusion du dossier spécifié

Vérifiez le dossier spécifié sous le dossier D:\Xunlei Download\, puis recherchez le mot clé ssssss dans tous les fichiers texte. Par défaut, les fichiers non textuels tels que la musique et la vidéo ne seront pas recherchés

    public static void main(String[] args) throws IOException {
    
    
        String dir = "D:\\迅雷下载\\";
        String searchStr ="ssssss";
        List<String> excludeDir = Arrays.asList("laydate"); //遇到文件夹名为laydate"则跳过该文件夹
        Map<String, Map<Integer, String>> map = SearchWord.searchAllFiles(dir, searchStr,excludeDir);
        System.out.println("");
        System.out.println("--------------------------------------------------------");
        System.out.println("搜索完成,结果:");
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

sortir:

正在扫描文件夹:D:\迅雷下载\
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1
正在扫描文件夹:D:\迅雷下载\layDate-v5.3.1\文档
正在扫描文件夹:D:\迅雷下载\test
正在扫描文件夹:D:\迅雷下载\新建文件夹
正在文件中搜索,当前搜索文件:D:\迅雷下载\aaa
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font\iconfont.eot
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\font\iconfont.woff
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\laydate\theme\default\laydate.css
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\test.html
正在文件中搜索,当前搜索文件:D:\迅雷下载\layDate-v5.3.1\文档\官网.url


--------------------------------------------------------
搜索完成,结果:
文件路径: D:\迅雷下载\aaa
第1行:ssssss

11. Utilisez-le comme un pot

    public static void main(String[] args) throws IOException {
    
    
        List<String> excludeDir = Arrays.asList("laydate"); //遇到文件夹名为"新建文件夹"则跳过该文件夹
        String dir = ""; //要扫描的文件夹
        String searchStr = ""; //要查找的字符串
        String[] array = null; //不查找的文件夹名
        for (int i = 0; i < args.length; i++) {
    
    
            if (i == 0) {
    
    
                dir = args[i];
            }else if (i == 1) {
    
    
                searchStr = args[i];
            }else if (i == 2) {
    
    
                String tempDirs = args[i];
                array = tempDirs.split(",");
            }
            System.out.println("参数" + (i + 1) + "的值为:" + args[i]);
        }
        Map<String, Map<Integer, String>> map = array == null ? SearchWord.searchAllFiles(dir, searchStr) : SearchWord.searchAllFiles(dir, searchStr, new ArrayList<>(Arrays.asList(array)));
        System.out.println("");
        System.out.println("--------------------------------------------------------");
        System.out.println("搜索完成,结果:");
        for (Map.Entry<String, Map<Integer, String>> m : map.entrySet()) {
    
    
            System.out.println("文件路径: " + m.getKey());
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                System.out.println("第" + n.getKey() + "行:" + n.getValue());
            }
            System.out.println();
        }
    }

Une fois empaqueté dans un package jar, il peut être utilisé sur le serveur. En supposant qu'il soit empaqueté en tant que scan.jar, la commande est la suivante :

java -jar scan.jar param1 param2 param3

Parmi eux, param1 est le dossier à analyser, param2 est la chaîne à rechercher et param3 est le nom du dossier à ne pas rechercher, séparés par des virgules

Par exemple :
recherchez les fichiers dans le dossier D:\myFiles\ et recherchez l'emplacement contenant la chaîne love, et ignorez le dossier s'il rencontre un dossier nommé move ou music

java -jar scan.jar D:\myFiles\ love move,music

12. Recherche multithread

Envisagez d'utiliser le multithreading pour créer un simple programme de chaîne de recherche multi-fichiers :
supposons qu'il existe trois paramètres folderPath, searchStr, containsSubFolder, qui représentent respectivement le chemin du dossier, la chaîne à rechercher et s'il faut rechercher des sous-répertoires.
Si containsSubFolder est false, recherchez uniquement les lignes de tous les fichiers lisibles sous le dossier folderPath (sans ses sous-répertoires) qui contiennent la chaîne de clé de searchStr et affichez le contenu de cette ligne ; si containsSubFolder est true, recherchez le dossier folderPath contenant
ses Quelles lignes contiennent la chaîne de clé searchStr dans tous les fichiers lisibles du sous-répertoire, et affichez le contenu de cette ligne.

Points à considérer :
1. Utilisez 2 threads :
- Le thread A analyse le chemin de tous les fichiers lisibles dans le dossier et les place dans la file d'attente ;
- Le thread B récupère en continu les données de chemin d'accès au fichier dans la file d'attente, puis recherche dans le fichier ;
2. Quand le thread B se termine-t-il :
- Après que le thread A a analysé, il doit renvoyer un indicateur au thread B pour lui indiquer que le thread A est terminé ;
- Lorsque le thread B sait que le thread A s'est terminé, le thread B doit déterminer s'il y a des données dans la file d'attente , sinon, cela signifie que tous les fichiers ont été recherchés et la recherche se terminera
3. Considérez la communication entre les threads, c'est-à-dire les variables partagées
4. Considérez quelle file d'attente utiliser pour stocker les données données par A thread et fournir des données au thread B
5. Considérer Le résultat n'est sorti qu'après l'exécution des deux threads A et B.

Le code suivant utilisera un pool de threads de longueur fixe pour créer deux threads, puis utilisera la file d'attente de blocage illimitée LinkedBlockingQueue pour recevoir des données du thread A et fournir des données au thread B, utiliser AtomicBoolean pour partager des variables entre les threads et utiliser CountDownLatch pour attendre les deux threads pour terminer l'exécution avant de sortir le résultat.

La classe d'outils SearchUtils est la suivante :

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

public class SearchUtils {
    
    

    //当在文件夹中搜索时,遇到以下常见的非文本文件则跳过
    public static List<String> excludeFileType = Arrays.asList(
            "jar", "zip", "rar", "7z", "tar", "gz", "xz", "bz2", "doc", "class", "pak",
            "xls", "ppt", "pdf", "docx", "xlsx", "pptx", "jpg", "jpge", "gif", "png",
            "xltd", "war", "hprof", "m4a", "swf", "mobi", "jpeg", "tiff", "svg", "psd",
            "mp3", "aac", "mp4", "avi", "flv", "mkv", "mkv", "mpeg", "msi", "tgz",
            "rmvb", "apk", "ts", "map", "car", "mov", "wav", "raw", "dll", "woff",
            "eot", "otf", "ico", "ttf", "ttc", "fon", "dl_", "pd_", "ex_", "etl",
            "sys", "iso", "isz", "esd", "wim", "gho", "dmg", "mpf", "exe", "ldf", "mdf");

    
	/**
     * 获取 folderPath 文件夹下的所有的可读文件的路径,并将 路径存入 allFilesPath 里
     *
     * @param folderPath  要搜索的文件夹路径
     * @param allFilesPath 可读文件的路径存放进allFilesPath
     * @param containsSubFolder 是否搜索子文件夹
     */
    public static void getAllReadFilessPath(String folderPath, BlockingQueue<String> allFilesPath, boolean containsSubFolder) {
    
    
        File file = new File(folderPath);
        File[] tempList = file.listFiles();
        //System.out.println("正在扫描文件夹:" + dirPath);
        if (null == tempList) {
    
    
            return;
        }
        for (int i = 0; i < tempList.length; i++) {
    
    
            String filePath = tempList[i].toString();
            String file_Type = filePath.substring(filePath.lastIndexOf(".") + 1).toLowerCase();;
            if (tempList[i].isFile()) {
    
    
                //如果是文件并且是可读的文本文件
                if (!excludeFileType.contains(file_Type)) {
    
    
                    try {
    
    
                        allFilesPath.put(filePath);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            } else {
    
    
                //如果是文件夹且要读取子文件夹
                if (containsSubFolder) {
    
    
                    getAllReadFilessPath(filePath, allFilesPath, containsSubFolder);
                }
            }
        }
    }

    
	/**
     * 不断从 allFilesPath 里取文件路径然后搜索文件中是否含有关键字,把结果存到 searchResult 里
     *
     * @param allFilesPath  用于从该队列中获取文件路径
     * @param searchStr 要搜索的关键字
     * @param searchResult 存放最终的结果
     * @param scanFinish 要搜索的关键字
     */
    public static void searchAllFiles(BlockingQueue<String> allFilesPath, String searchStr, Map<String, Map<Integer, String>> searchResult, AtomicBoolean scanFinish) {
    
    
        while (true) {
    
    
            String filePath = null;
            try {
    
    
                filePath = allFilesPath.poll(1, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            //在 filePath 文件中搜索 searchStr 关键字
            Map<Integer, String> map = scanFile(filePath, searchStr);
            if (map.size() != 0) {
    
    
                searchResult.put(filePath, map);
            }
            if (allFilesPath.size() == 0 && scanFinish.get()) {
    
    
                //若队列中的数据已经取完并且扫描线程也已经扫描完就跳出循环
                break;
            }
        }
    }

    /**
     * 搜索指定文件中的关键字
     *
     * @param filePath  要搜索的文件路径
     * @param searchStr 要搜索的关键字
     * @return 返回的 map<行数, 该行内容>
     */
    public static Map<Integer, String> scanFile(String filePath, String searchStr) {
    
    
        Map<Integer, String> map = new LinkedHashMap<>();
        if (filePath == null) {
    
    
            return map;
        }
        FileInputStream file = null; //读取文件为字节流
        try {
    
    
            file = new FileInputStream(filePath);
            InputStreamReader in = new InputStreamReader(file, StandardCharsets.UTF_8); //字节流转化为字符流,以UTF-8读取防止中文乱码
            BufferedReader buf = new BufferedReader(in); //加入到缓存区
            String str = "";
            int row = 1;
            while ((str = buf.readLine()) != null) {
    
     //按行读取,到达最后一行返回null
                if (str.contains(searchStr)) {
    
    
                    map.put(row, str);
                }
                row++;
            }
            buf.close();
            file.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return map;
    }
}



Code multithread :

   public static void main(String[] args) throws Exception {
    
    
		//搜索 F 盘及其子文件夹下所有可读文件中那些文件包含 "g789d" 关键字
        Map<String, Map<Integer, String>> searchResult = search("F:\\", "g789d", true);
        StringBuffer result = new StringBuffer();
        for (Map.Entry<String, Map<Integer, String>> m : searchResult.entrySet()) {
    
    
            result.append("  文件: " + m.getKey());
            result.append("\n");
            for (Map.Entry<Integer, String> n : m.getValue().entrySet()) {
    
    
                result.append("\t第 " + n.getKey() + " 行:" + n.getValue() + "\n");
            }
            result.append("\n\n ");
        }
        System.out.println(result.toString());

    }

    public static Map<String, Map<Integer, String>> search( String folderPath, String searchStr, boolean containsSubFolder){
    
    
        //存储所有的扫描的可读文件的路径
        BlockingQueue<String> allFilesPath = new LinkedBlockingQueue<>();
        //用于判断扫描线程是否已扫描完成
        AtomicBoolean scanFinish = new AtomicBoolean(false);
        //存储所有搜索的结果<文件名,<行数,内容>>
        Map<String, Map<Integer, String>> searchResult = new LinkedHashMap<>();
        //线程计数器
        CountDownLatch countDownLatch = new CountDownLatch(2);

        //创建一个定长线程池,初始化为2
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);

        //创建一个线程用于扫描所有的可读文件路径,然后存放到 allFilesPath 里,扫描完将 scanFinish 设为 true
        fixedThreadPool.execute(() -> {
    
    
            SearchUtils.getAllReadFilessPath(folderPath, allFilesPath, containsSubFolder);
            scanFinish.set(true);//当此线程扫描完所有线程后将scanFinish设置为true
            countDownLatch.countDown();//线程计数器减一
        });

        //创建一个线程不断从 allFilesPath 里取文件路径然后搜索文件中是否含有关键字,把结果存到 searchResult 里,
        // 当 allFilesPath 为空并且 scanFinish 为true (即上面的线程扫描完了,此线程也把 allFilesPath 里的所有的文件扫描完了),就跳出searchAllFiles方法
        fixedThreadPool.execute(() -> {
    
    
            SearchUtils.searchAllFiles(allFilesPath, searchStr, searchResult, scanFinish);
            countDownLatch.countDown();
        });

        try {
    
    
            //等待上面两个线程执行完
            countDownLatch.await();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        //关闭线程池
        fixedThreadPool.shutdown();
        return searchResult;
    }

résultat:

  文件: F:\asposeHtml\aa_files\we.txt
	第 4 行:fhfg789dfrh

   文件: F:\fileTypeTest\havaAttachFile\we.txt
	第 4 行:fhfg789dfrh

   文件: F:\spireHtml\myExcel_files\we.txt
	第 4 行:fhfg789dfrh

   文件: F:\we.txt
	第 4 行:fhfg789dfrh
	第 8 行:fhfg789dfrh
	第 12 行:fhfg789dfrh

   文件: F:\ydz\test\新建文件夹\we.txt
	第 4 行:fhfg789dfrh

Cet exemple est juste un simple problème de producteur et de consommateur, et il n'y a qu'un seul producteur et consommateur. S'il y a plusieurs producteurs et consommateurs, vous pouvez vous référer à :

Producteur Consommateur Solution utilisant BlockingQueue dans Java Thread
Producer-Consumer Problem With Example in Java

Je suppose que tu aimes

Origine blog.csdn.net/qq_33697094/article/details/122237127
conseillé
Classement