Индивидуальная практическая работа

Цель работы:

Изучение возможностей языка Java для работы с потоками и параллельными вычислениями.

Задание

Написать программу, которая в заданном каталоге находит все файлы, содержащие определённую последовательность символов. Количество одновременно открытых вводится отдельно, каждый файл открывается в своём потоке.

Исходный код программы:

import java.io.*; import java.nio.file.*; import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; public class FileSearcher { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Введите путь к каталогу: "); String directory = scanner.nextLine(); System.out.print("Введите искомую последовательность символов: "); String searchText = scanner.nextLine(); System.out.print("Введите максимальное количество одновременно открытых файлов: "); int maxThreads = scanner.nextInt(); scanner.close(); try { searchInDirectory(directory, searchText, maxThreads); } catch (IOException e) { System.err.println("Ошибка при работе с файловой системой: " + e.getMessage()); } } public static void searchInDirectory(String directoryPath, String searchText, int maxThreads) throws IOException { Path startPath = Paths.get(directoryPath); if (!Files.exists(startPath)) { System.err.println("Каталог не существует: " + directoryPath); return; } // Получаем список всех файлов в каталоге и подкаталогах List<Path> files = Files.walk(startPath) .filter(Files::isRegularFile) .collect(Collectors.toList()); System.out.println("Найдено файлов: " + files.size()); System.out.println("Начинаем поиск...\n"); // Создаём пул потоков с ограниченным количеством ExecutorService executor = Executors.newFixedThreadPool(maxThreads); List<Future<SearchResult>> futures = new ArrayList<>(); // Отправляем задачи на выполнение for (Path file : files) { Future<SearchResult> future = executor.submit(new FileSearchTask(file, searchText)); futures.add(future); } // Ожидаем завершения всех задач и собираем результаты List<SearchResult> results = new ArrayList<>(); for (Future<SearchResult> future : futures) { try { SearchResult result = future.get(); if (result.isFound()) { results.add(result); } } catch (InterruptedException | ExecutionException e) { System.err.println("Ошибка при обработке файла: " + e.getMessage()); } } // Завершаем работу пула потоков executor.shutdown(); try { executor.awaitTermination(1, TimeUnit.MINUTES); } catch (InterruptedException e) { System.err.println("Прерывание при ожидании завершения потоков"); } // Выводим результаты System.out.println("\n=== РЕЗУЛЬТАТЫ ПОИСКА ==="); if (results.isEmpty()) { System.out.println("Файлы с указанной последовательностью не найдены."); } else { System.out.println("Найдено файлов: " + results.size() + "\n"); for (SearchResult result : results) { System.out.println("Файл: " + result.getFilePath()); System.out.println(" Найдено вхождений: " + result.getOccurrences()); System.out.println(); } } } // Класс для хранения результатов поиска static class SearchResult { private final String filePath; private final boolean found; private final int occurrences; public SearchResult(String filePath, boolean found, int occurrences) { this.filePath = filePath; this.found = found; this.occurrences = occurrences; } public String getFilePath() { return filePath; } public boolean isFound() { return found; } public int getOccurrences() { return occurrences; } } // Задача для поиска в одном файле static class FileSearchTask implements Callable<SearchResult> { private final Path file; private final String searchText; public FileSearchTask(Path file, String searchText) { this.file = file; this.searchText = searchText; } @Override public SearchResult call() { String threadName = Thread.currentThread().getName(); System.out.println("[" + threadName + "] Обработка файла: " + file.getFileName()); int occurrences = 0; boolean found = false; try (BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(file.toFile()), "UTF-8"))) { String line; while ((line = reader.readLine()) != null) { int index = 0; while ((index = line.indexOf(searchText, index)) != -1) { occurrences++; index += searchText.length(); found = true; } } if (found) { System.out.println("[" + threadName + "] ✓ Найдено в: " + file.getFileName()); } } catch (IOException e) { System.err.println("[" + threadName + "] Ошибка при чтении файла " + file.getFileName() + ": " + e.getMessage()); } return new SearchResult(file.toString(), found, occurrences); } } }
Назад