Table des matières
-
-
- avant-propos
- 1. Outils
- 2. Analysez tous les fichiers du dossier
- 3. Analysez tous les fichiers sous le dossier, excluez le dossier spécifié
- 4. Analysez le type de fichiers spécifié dans le dossier
- 5. Analysez le type de fichiers spécifié sous le dossier et excluez le dossier spécifié
- 6. Rechercher une chaîne dans le fichier spécifié
- 7. Rechercher des chaînes dans des fichiers d'un type spécifié sous un dossier
- 8. Rechercher des chaînes dans des fichiers d'un type spécifié sous un dossier, à l'exclusion des dossiers spécifiés
- 9. Rechercher une chaîne dans tous les fichiers lisibles du dossier spécifié
- 10. Rechercher des chaînes dans tous les fichiers lisibles sous le dossier spécifié, à l'exclusion du dossier spécifié
- 11. Utilisez-le comme un pot
- 12. Recherche multithread
-
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大小:3
第68行:[http-nio-8080-exec-339 2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:42
第69行:[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大小:3
第68行:[http-nio-8080-exec-339 2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:42
第69行:[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-14
第19行:insertData-firmpv:1
第20行:insertData-firmuv:1
第21行:insertData-userpv:1
第22行: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大小:3
第68行:[http-nio-8080-exec-339 2021 Dec 27 15:10:42]insertData-nowadays:2021-12-27 15:10:42
第69行:[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