Задание
Написать программу, которая в заданном каталоге находит все файлы, содержащие определённую последовательность символов. Количество одновременно открытых вводится отдельно, каждый файл открывается в своём потоке.
Исходный код программы:
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);
}
}
}