Java 打印目录下所有文件包含指定关键字的行

在一个目录及其子所有子目录下搜索所有文件,打印包含指定关键字的行

代码实现:

 1 public class BlockingQueueTest {
 2 
 3     private static final int FILE_QUEUE_SIZE = 10;
 4     private static final int SEARCH_THREADS = 100;
 5     private static final Path DUMMY = Path.of("");
 6     private static BlockingQueue<Path> queue = new ArrayBlockingQueue<>(FILE_QUEUE_SIZE);
 7 
 8     // 12.5.1 阻塞队列
 9     public static void main(String[] args) {
10 
11         try (var in = new Scanner(System.in)) {
12             System.out.print("Enter base directory (e.g. C:\\Files\\test):");
13             String directory = in.nextLine();
14 
15             System.out.print("Enter keyword (e.g. volatile)");
16             String keyword = in.nextLine();
17 
18             Runnable enumerator = () -> {
19                 try {
20                     enumerate(Path.of(directory));
21                     queue.put(DUMMY);
22 
23                 } catch (IOException e) {
24                     e.printStackTrace();
25                 } catch (InterruptedException e) {
26                     e.printStackTrace();
27                 }
28             };
29 
30             new Thread(enumerator).start();
31 
32             for (int i = 1; i < SEARCH_THREADS; i++) {
33                 Runnable searcher = () -> {
34                     try {
35                         var done = false;
36                         while (!done) {
37                             Path file = queue.take();
38                             if (file == DUMMY) {
39                                 queue.put(file);
40                                 done = true;
41                             } else {
42                                 search(file, keyword);
43                             }
44                         }
45                     } catch (IOException e) {
46                         e.printStackTrace();
47                     } catch (InterruptedException e) {
48                         e.printStackTrace();
49                     }
50                 };
51                 new Thread(searcher).start();
52             }
53         }
54     }
55 
56     /**
57      * Recursively enumerates all files in a given directory and its subdirectories.
58      *
59      * @param directory the directory in which to start.
60      * @return void
61      */
62     public static void enumerate(Path directory) throws IOException, InterruptedException {
63 
64         try (Stream<Path> children = Files.list(directory)) {
65             for (Path child : children.collect(Collectors.toList())) {
66                 if (Files.isDirectory(child))
67                     enumerate(child);
68                 else
69                     queue.put(child);
70 
71             }
72         }
73     }
74 
75     /**
76      * Search a file for a given keyword and prints all matching lines.
77      *
78      * @param file    the file to search
79      * @param keyword the key word to search for
80      * @return void
81      */
82     public static void search(Path file, String keyword) throws IOException {
83 
84         try (var in = new Scanner(file, StandardCharsets.UTF_8)) {
85             int lineNumber = 0;
86 
87             while (in.hasNextLine()) {
88                 lineNumber++;
89                 String line = in.nextLine();
90                 if (line.contains(keyword))
91                     System.out.printf("%s:%d:%s%n", file, lineNumber, line);
92             }
93         }
94     }
95 }

 

posted @ 2020-12-18 15:32  宁任翃  阅读(249)  评论(0编辑  收藏  举报