выполненное 2 задание

This commit is contained in:
salih
2025-12-15 14:01:56 +04:00
parent 312b184706
commit 1ed07f266e
10 changed files with 193 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
# Лабораторная 2 — два Javaворкера под Docker Compose
## Цели и задачи
- Реализовать два приложения, где выход первого является входом второго.
- Собрать образы через Dockerfile и запустить вместе через docker-compose.
- Отработать маунты каталогов с хоста в контейнеры.
## Описание программы
- `worker-1`: читает каталог `/var/data`, берет первую строку из каждого файла и пишет их в `/var/result/data.txt`.
- `worker-2`: читает числа из `/var/data/data.txt`, находит минимальное, считает число вхождений, сохраняет счетчик в `/var/result/result.txt` и выводит результат в консоль.
## Используемые технологии
- Java 17 (Eclipse Temurin JDK).
- Docker + Docker Compose (два сервиса, отдельные Dockerfile).
## Описание работы
### Выбранные варианта:
Вариант программы 1:
- 2 Формирует файл /var/result/data.txt из первых строк всех файлов каталога /var/data.
Вариант программы 2:
- 4 Ищет наименьшее число из файла /var/data/data.txt и сохраняет количество таких чисел из последовательности в /var/result/result.txt.
### Описание работы
1. `worker-1` получает файлы с целыми числами (по одному набору в первой строке) из примонтированного каталога `/var/data` и формирует объединенный файл `data.txt` в `/var/result`.
2. `worker-2` ждет появления `data.txt`, затем считывает все числа, находит минимум и количество его повторов, пишет счетчик в `result.txt`, выводит минимум и счетчик в stdout.
## Инструкция по запуску
1. Docker и Docker Compose должны быть установлены установлены
2. В каталог `input/` положите входные файлы с числами (в файлах уже есть тестовые данные).
3. Из каталога `yaruskin_salikh_lab_2` выполните:
```sh
docker compose up --build
```
4. Результаты:
- Объединенный файл после `worker-1`: `shared/data.txt`.
- Итог `worker-2`: `output/result.txt` и вывод в логах контейнера `worker2`.
5. Ссылка на видео:
https://disk.yandex.ru/i/httWu3SrCr2liw

View File

@@ -0,0 +1,15 @@
services:
worker1:
build: ./worker-1
volumes:
- ./input:/var/data:ro
- ./shared:/var/result
worker2:
build: ./worker-2
depends_on:
- worker1
command: ["/bin/sh", "-c", "while [ ! -f /var/data/data.txt ]; do echo 'Waiting for data from worker1...'; sleep 1; done; exec java Main"]
volumes:
- ./shared:/var/data
- ./output:/var/result

View File

@@ -0,0 +1 @@
10 5 3 3 9

View File

@@ -0,0 +1 @@
7 7 2 2 5 2

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,2 @@
10 5 3 3 9
7 7 2 2 5 2

View File

@@ -0,0 +1,14 @@
# Используем официальный базовый образ Eclipse Temurin с JDK 17
FROM eclipse-temurin:17-jdk-jammy
# Создаем рабочую директорию внутри контейнера
WORKDIR /app
# Копируем исходный код приложения в образ
COPY Main.java .
# Компилируем Java-файл в байткод
RUN javac Main.java
# Запускаем приложение; каталоги /var/data и /var/result приходят через маунты
CMD ["java", "Main"]

View File

@@ -0,0 +1,47 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path inputDir = Paths.get("/var/data");
Path outputDir = Paths.get("/var/result");
Path outputFile = outputDir.resolve("data.txt");
try {
Files.createDirectories(outputDir);
if (!Files.isDirectory(inputDir)) {
System.out.println("Input directory does not exist: " + inputDir);
return;
}
List<String> firstLines = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(inputDir)) {
for (Path path : stream) {
if (Files.isRegularFile(path)) {
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
String line = reader.readLine();
if (line != null) {
firstLines.add(line.trim());
}
}
}
}
}
Files.write(outputFile, firstLines, StandardCharsets.UTF_8,
java.nio.file.StandardOpenOption.CREATE,
java.nio.file.StandardOpenOption.TRUNCATE_EXISTING);
System.out.println("Collected " + firstLines.size() + " lines into " + outputFile);
} catch (IOException e) {
System.err.println("Failed to build data file: " + e.getMessage());
System.exit(1);
}
}
}

View File

@@ -0,0 +1,14 @@
# Базовый образ с JDK 17: достаточен для компиляции и запуска Java-приложения
FROM eclipse-temurin:17-jdk-jammy
# Рабочая директория, куда копируем исходники
WORKDIR /app
# Копируем исходный файл приложения внутрь образа
COPY Main.java .
# Компилируем Main.java
RUN javac Main.java
# Точка входа контейнера — запуск скомпилированного класса
CMD ["java", "Main"]

View File

@@ -0,0 +1,60 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Path inputFile = Paths.get("/var/data/data.txt");
Path outputDir = Paths.get("/var/result");
Path outputFile = outputDir.resolve("result.txt");
try {
if (!Files.exists(inputFile)) {
System.err.println("Input file not found: " + inputFile);
System.exit(1);
}
List<Integer> numbers = readNumbers(inputFile);
if (numbers.isEmpty()) {
System.err.println("Input file is empty or has no numbers.");
System.exit(1);
}
int minValue = numbers.stream().min(Integer::compareTo).orElseThrow();
long count = numbers.stream().filter(n -> n == minValue).count();
Files.createDirectories(outputDir);
Files.writeString(outputFile, String.valueOf(count), StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
System.out.println("Min value: " + minValue + ", count: " + count);
} catch (Exception e) {
System.err.println("Failed to process file: " + e.getMessage());
System.exit(1);
}
}
private static List<Integer> readNumbers(Path inputFile) throws IOException {
List<String> lines = Files.readAllLines(inputFile, StandardCharsets.UTF_8);
List<Integer> numbers = new ArrayList<>();
for (String line : lines) {
if (line == null) {
continue;
}
String[] parts = line.trim().split("\\s+");
for (String part : parts) {
if (!part.isEmpty()) {
numbers.add(Integer.parseInt(part));
}
}
}
return numbers;
}
}