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 }