Open kotAlicekot opened 20 hours ago
//25
typedef struct {
char path[1024];
FILE output_file;
} ThreadArgs;
void print_error(const char module_name, const char message) {
fprintf(stderr, "%s: %s\n", module_name, message);
}
void process_directory(void args) {
ThreadArgs threadArgs = (ThreadArgs )args;
const char dir_path = threadArgs->path;
FILE output_file = threadArgs->output_file;
DIR dir;
struct dirent entry;
struct stat file_stat;
int file_count = 0;
size_t total_size = 0;
char largest_file[256];
size_t largest_size = 0;
char path[1024];
if (!(dir = opendir(dir_path))) {
print_error("./1.exe", "Error opening directory");
return NULL;
}
while ((entry = readdir(dir)) != NULL) {
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);
if (stat(path, &file_stat) == -1) {
print_error("./1.exe", "Error getting file stats");
continue;
}
if (S_ISREG(file_stat.st_mode)) {
file_count++;
total_size += file_stat.st_size;
if (file_stat.st_size > largest_size) {
largest_size = file_stat.st_size;
strcpy(largest_file, entry->d_name);
}
printf("%d: %s %zu\n", getpid(), path, file_stat.st_size);
}
}
fprintf(output_file, "%s: %d %zu %s\n", dir_path, file_count, total_size, largest_file);
closedir(dir);
return NULL;
}
int main(int argc, char argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s
if (!output_file) {
print_error(argv[0], "Error opening output file");
return 1;
}
DIR *dir;
struct dirent *entry;
char path[1024];
int thread_count = 0;
pthread_t threads[MAX_THREADS];
ThreadArgs thread_args[MAX_THREADS];
if (!(dir = opendir(directory))) {
print_error(argv[0], "Error opening directory");
return 1;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
strcpy(thread_args[thread_count].path, path);
thread_args[thread_count].output_file = output_file;
if (pthread_create(&threads[thread_count], NULL, process_directory, &thread_args[thread_count]) != 0) {
print_error(argv[0], "Error creating thread");
closedir(dir);
return 1;
}
thread_count++;
if (thread_count >= MAX_THREADS) {
for (int i = 0; i < MAX_THREADS; i++) {
pthread_join(threads[i], NULL);
}
thread_count = 0;
}
}
}
closedir(dir);
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
fclose(output_file);
return 0;
}
typedef struct { char path[PATH_MAX_LENGTH]; FILE *output_file; } ThreadArgs;
void print_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void process_directory(void args) { ThreadArgs threadArgs = (ThreadArgs )args; const char dir_path = threadArgs->path; FILE output_file = threadArgs->output_file;
DIR *dir;
struct dirent *entry;
struct stat file_stat;
int file_count = 0;
size_t total_size = 0;
char largest_file[256];
size_t largest_size = 0;
char path[PATH_MAX_LENGTH];
if (!(dir = opendir(dir_path))) {
print_error("./1.exe", "Error opening directory");
return NULL;
}
while ((entry = readdir(dir)) != NULL) {
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);
if (stat(path, &file_stat) == -1) {
print_error("./1.exe", "Error getting file stats");
continue;
}
if (S_ISREG(file_stat.st_mode)) {
file_count++;
total_size += file_stat.st_size;
if (file_stat.st_size > largest_size) {
largest_size = file_stat.st_size;
strcpy(largest_file, entry->d_name);
}
printf("%d: %s %zu\n", getpid(), path, file_stat.st_size);
}
}
fprintf(output_file, "%s: %d %zu %s\n", dir_path, file_count, total_size, largest_file);
closedir(dir);
return NULL;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s
const char *directory = argv[1];
const char *output_filename = argv[2];
FILE *output_file = fopen(output_filename, "w");
if (!output_file) {
print_error(argv[0], "Error opening output file");
return 1;
}
DIR *dir;
struct dirent *entry;
char path[PATH_MAX_LENGTH];
int thread_count = 0;
pthread_t threads[MAX_THREADS];
ThreadArgs thread_args[MAX_THREADS];
if (!(dir = opendir(directory))) {
print_error(argv[0], "Error opening directory");
return 1;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
snprintf(path, sizeof(path), "%s/%s", directory, entry->d_name);
strncpy(thread_args[thread_count].path, path, PATH_MAX_LENGTH);
thread_args[thread_count].output_file = output_file;
if (pthread_create(&threads[thread_count], NULL, process_directory, &thread_args[thread_count]) != 0) {
print_error(argv[0], "Error creating thread");
closedir(dir);
return 1;
}
thread_count++;
if (thread_count >= MAX_THREADS) {
for (int i = 0; i < MAX_THREADS; i++) {
pthread_join(threads[i], NULL);
}
thread_count = 0;
}
}
}
closedir(dir);
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
fclose(output_file);
return 0;
}
// Use PATH_MAX instead of a hardcoded limit. This is more portable. // #define PATH_MAX_LENGTH 4096 //Avoid hardcoded limits. Use PATH_MAX instead
typedef struct { char path; // Use char for dynamic allocation, more flexible than fixed-size array FILE *output_file; } ThreadArgs;
// ... (print_error function remains unchanged) ...
void process_directory(void args) { ThreadArgs threadArgs = (ThreadArgs )args; char dir_path = threadArgs->path; //Use char FILE *output_file = threadArgs->output_file;
DIR *dir;
struct dirent *entry;
struct stat file_stat;
int file_count = 0;
size_t total_size = 0;
char *largest_file = NULL; // Dynamically allocate for safety
size_t largest_size = 0;
char path[PATH_MAX]; //Use PATH_MAX
if (!(dir = opendir(dir_path))) {
print_error("./1.exe", "Error opening directory");
return NULL;
}
while ((entry = readdir(dir)) != NULL) {
// Corrected snprintf with error checking and proper format string:
int r = snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);
if (r >= sizeof(path) || r < 0) {
print_error("./1.exe", "Path too long!");
continue;
}
if (stat(path, &file_stat) == -1) {
print_error("./1.exe", "Error getting file stats");
continue;
}
if (S_ISREG(file_stat.st_mode)) {
file_count++;
total_size += file_stat.st_size;
if (file_stat.st_size > largest_size) {
largest_size = file_stat.st_size;
// Free previous largest_file if it exists.
free(largest_file);
largest_file = strdup(entry->d_name); // safer than strcpy
if (largest_file == NULL) {
print_error("./1.exe", "Memory allocation failed!");
return NULL;
}
}
printf("%d: %s %zu\n", getpid(), path, file_stat.st_size);
}
}
//Corrected fprintf:
fprintf(output_file, "%s: %d %zu %s\n", dir_path, file_count, total_size, largest_file ? largest_file : "");
free(largest_file); // Free dynamically allocated memory
closedir(dir);
return NULL;
}
int main(int argc, char *argv[]) { // ... (main function remains largely the same, but with changes below)
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
//Dynamically allocate memory for the path
char *path = (char*)malloc(PATH_MAX);
if(path == NULL){
print_error(argv[0],"Memory allocation failed!");
return 1;
}
int r = snprintf(path, PATH_MAX, "%s/%s", directory, entry->d_name);
if(r >= PATH_MAX || r < 0){
print_error(argv[0],"Path too long!");
free(path);
continue;
}
thread_args[thread_count].path = path; //Use char*
thread_args[thread_count].output_file = output_file;
//... (rest of main remains largely the same but with error checks) ...
free(thread_args[thread_count].path); //Free memory after creating the thread
}
}
// ... (rest of main remains largely the same) ...
}
typedef struct { char path; FILE output_file; long file_count; // Add file count to struct long total_size; // Add total size to struct char largest_file[PATH_MAX]; // Increase size if necessary long largest_size; // Add largest size to struct pthread_mutex_t mutex; //mutex for thread-safe access to shared resources } ThreadArgs;
void print_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void process_directory(void args) { ThreadArgs threadArgs = (ThreadArgs )args; char dir_path = threadArgs->path; FILE output_file = threadArgs->output_file;
DIR *dir;
struct dirent *entry;
struct stat file_stat;
long file_count = 0;
long total_size = 0;
char largest_file[PATH_MAX];
long largest_size = 0;
char full_path[PATH_MAX];
if (!(dir = opendir(dir_path))) {
print_error("process_directory", "Error opening directory");
return NULL;
}
while ((entry = readdir(dir)) != NULL) {
int r = snprintf(full_path, PATH_MAX, "%s/%s", dir_path, entry->d_name);
if (r >= PATH_MAX || r < 0) {
print_error("process_directory", "Path too long!");
continue;
}
if (stat(full_path, &file_stat) == -1) {
print_error("process_directory", "Error getting file stats");
continue;
}
if (S_ISREG(file_stat.st_mode)) {
pthread_mutex_lock(&threadArgs->mutex); // Lock before accessing shared variables
file_count++;
total_size += file_stat.st_size;
if (file_stat.st_size > largest_size) {
largest_size = file_stat.st_size;
strncpy(largest_file, entry->d_name, PATH_MAX);
}
pthread_mutex_unlock(&threadArgs->mutex); // Unlock
printf("%lu: %s %ld %ld\n", (unsigned long)pthread_self(), full_path, file_stat.st_size, file_count);
}
}
pthread_mutex_lock(&threadArgs->mutex); // Lock before updating shared variables
threadArgs->file_count = file_count;
threadArgs->total_size = total_size;
strncpy(threadArgs->largest_file, largest_file, PATH_MAX);
threadArgs->largest_size = largest_size;
pthread_mutex_unlock(&threadArgs->mutex); // Unlock
fprintf(output_file, "%s: %ld %ld %s\n", dir_path, threadArgs->file_count, threadArgs->total_size, threadArgs->largest_file);
closedir(dir);
return NULL;
}
int main(int argc, char *argv[]) { // ... (main function largely remains the same, but with changes below)
int max_threads;
printf("Enter maximum number of concurrent threads: ");
if (scanf("%d", &max_threads) != 1 || max_threads <= 0) {
print_error(argv[0], "Invalid number of threads.");
fclose(output_file);
return 1;
}
pthread_t threads[MAX_THREADS];
ThreadArgs thread_args[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
char *subdir_path = (char*)malloc(PATH_MAX);
if(subdir_path == NULL){
print_error(argv[0],"Memory allocation failed!");
return 1;
}
int r = snprintf(subdir_path, PATH_MAX, "%s/%s", directory, entry->d_name);
if(r >= PATH_MAX || r < 0){
print_error(argv[0],"Path too long!");
free(subdir_path);
continue;
}
thread_args[thread_count].path = subdir_path;
thread_args[thread_count].output_file = output_file;
pthread_mutex_init(&thread_args[thread_count].mutex, NULL); // Initialize mutex
if (pthread_create(&threads[thread_count], NULL, process_directory, &thread_args[thread_count]) != 0) {
print_error(argv[0], "Error creating thread");
free(subdir_path); //Free memory
return 1;
}
thread_count++;
if (thread_count >= max_threads) {
for (int i = 0; i < max_threads; i++) {
pthread_join(threads[i], NULL);
pthread_mutex_destroy(&thread_args[i].mutex); // Destroy mutex
free(thread_args[i].path); //Free path memory
}
thread_count = 0;
}
}
}
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
pthread_mutex_destroy(&thread_args[i].mutex); // Destroy mutex
free(thread_args[i].path); //Free path memory
}
// ... (rest of main function remains largely the same) ...
}
// ... (your print_error and process_directory functions would go here) ...
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s
char *directory = argv[1]; //Corrected: use char * instead of const char *
char *output_filename = argv[2]; //Corrected: use char * instead of const char *
FILE *output_file;
// Open the output file *before* using it. Check if opening the file fails.
output_file = fopen(output_filename, "w");
if (output_file == NULL) {
print_error(argv[0], "Error opening output file");
return 1;
}
DIR *dir;
struct dirent *entry;
char subdir_path[PATH_MAX]; //Make sure subdir_path is large enough
// Open the directory. Check for errors.
if (!(dir = opendir(directory))) {
print_error(argv[0], "Error opening directory");
fclose(output_file); //Close file before exiting.
return 1;
}
// ... (the rest of your main function using the properly declared variables) ...
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
int r = snprintf(subdir_path, PATH_MAX, "%s/%s", directory, entry->d_name);
if (r >= PATH_MAX || r < 0) {
print_error(argv[0], "Path too long!");
continue; //Skip to the next iteration
}
// Pass subdir_path and output_file to your thread function.
// ... (Your thread creation and joining code would go here) ...
}
}
closedir(dir);
fclose(output_file); // Close the output file after use
return 0;
}
typedef struct { char path[MAX_PATH]; FILE *output_file; } ThreadData;
void process_directory(void arg); void handle_error(const char module_name, const char message);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s
const char *dir_path = argv[1];
const char *output_file_path = argv[2];
FILE *output_file = fopen(output_file_path, "w");
if (output_file == NULL) {
handle_error(argv[0], "Error opening output file");
return EXIT_FAILURE;
}
ThreadData data = { .output_file = output_file };
strncpy(data.path, dir_path, MAX_PATH);
pthread_t threads[MAX_THREADS];
int thread_count = 0;
// Создаем первый поток для обработки корневого каталога
if (pthread_create(&threads[thread_count++], NULL, process_directory, &data) != 0) {
handle_error("main", "Error creating thread");
fclose(output_file);
return EXIT_FAILURE;
}
// Ожидаем завершения всех потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
fclose(output_file);
return EXIT_SUCCESS;
}
void process_directory(void arg) { ThreadData data = (ThreadData )arg; const char path = data->path; FILE output_file = data->output_file;
DIR *dir = opendir(path);
if (dir == NULL) {
handle_error("process_directory", "Error opening directory");
return NULL;
}
struct dirent *entry;
struct stat file_stat;
pthread_t threads[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем '.' и '..'
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
if (stat(full_path, &file_stat) == -1) {
handle_error("process_directory", "Error getting file status");
continue;
}
if (S_ISDIR(file_stat.st_mode)) {
// Создаем новый поток для обработки подкаталога
if (thread_count < MAX_THREADS) {
ThreadData new_data = { .output_file = output_file };
strncpy(new_data.path, full_path, MAX_PATH);
if (pthread_create(&threads[thread_count++], NULL, process_directory, &new_data) != 0) {
handle_error("process_directory", "Error creating thread");
}
} else {
// Ожидаем завершения одного из потоков
pthread_join(threads[--thread_count], NULL);
}
} else {
// Обработка файла
printf("Thread ID: %lu, Path: %s, Size: %ld\n", pthread_self(), full_path, file_stat.st_size);
fprintf(output_file, "File: %s, Size: %ld\n", full_path, file_stat.st_size);
}
}
closedir(dir);
// Ожидание завершения всех дочерних потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
return NULL;
}
void handle_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
typedef struct { char path[MAX_PATH]; FILE *output_file; } ThreadData;
void process_directory(void arg); void handle_error(const char module_name, const char message);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s
const char *dir_path = argv[1];
const char *output_file_path = argv[2];
FILE *output_file = fopen(output_file_path, "w");
if (output_file == NULL) {
handle_error(argv[0], "Error opening output file");
return EXIT_FAILURE;
}
ThreadData data = { .output_file = output_file };
strncpy(data.path, dir_path, MAX_PATH);
pthread_t threads[MAX_THREADS];
int thread_count = 0;
// Создаем первый поток для обработки корневого каталога
if (pthread_create(&threads[thread_count++], NULL, process_directory, &data) != 0) {
handle_error("main", "Error creating thread");
fclose(output_file);
return EXIT_FAILURE;
}
// Ожидаем завершения всех потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
fclose(output_file);
return EXIT_SUCCESS;
}
void process_directory(void arg) { ThreadData data = (ThreadData )arg; const char path = data->path; FILE output_file = data->output_file;
DIR *dir = opendir(path);
if (dir == NULL) {
handle_error("process_directory", "Error opening directory");
return NULL;
}
struct dirent *entry;
struct stat file_stat;
pthread_t threads[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем '.' и '..'
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
if (stat(full_path, &file_stat) == -1) {
handle_error("process_directory", "Error getting file status");
continue;
}
if (S_ISDIR(file_stat.st_mode)) {
// Создаем новый поток для обработки подкаталога
if (thread_count < MAX_THREADS) {
ThreadData new_data = { .output_file = output_file };
strncpy(new_data.path, full_path, MAX_PATH);
if (pthread_create(&threads[thread_count++], NULL, process_directory, &new_data) != 0) {
handle_error("process_directory", "Error creating thread");
}
} else {
// Ожидаем завершения одного из потоков
pthread_join(threads[--thread_count], NULL);
}
} else {
// Обработка файла
printf("Thread ID: %lu, Path: %s, Size: %ld\n", pthread_self(), full_path, file_stat.st_size);
fprintf(output_file, "File: %s, Size: %ld\n", full_path, file_stat.st_size);
}
}
closedir(dir);
// Ожидание завершения всех дочерних потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
return NULL;
}
void handle_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void process_directory(void arg); void handle_error(const char module_name, const char message); void list_files(const char path, FILE output_file);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s
const char *dir_path = argv[1];
const char *output_file_path = argv[2];
FILE *output_file = fopen(output_file_path, "w");
if (output_file == NULL) {
handle_error(argv[0], "Error opening output file");
return EXIT_FAILURE;
}
// Запускаем обработку директории
list_files(dir_path, output_file);
fclose(output_file);
return EXIT_SUCCESS;
}
void list_files(const char path, FILE output_file) { DIR *dir = opendir(path); if (dir == NULL) { handle_error("list_files", "Error opening directory"); return; }
struct dirent *entry;
pthread_t threads[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем '.' и '..'
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
struct stat file_stat;
if (stat(full_path, &file_stat) == -1) {
handle_error("list_files", "Error getting file status");
continue;
}
if (S_ISDIR(file_stat.st_mode)) {
// Создаем новый поток для обработки подкаталога
if (thread_count < MAX_THREADS) {
// Создаем новый поток
char *path_copy = strdup(full_path); // Копируем путь
if (pthread_create(&threads[thread_count++], NULL, process_directory, path_copy) != 0) {
handle_error("list_files", "Error creating thread");
free(path_copy);
}
} else {
// Ожидаем завершения одного из потоков
pthread_join(threads[--thread_count], NULL);
}
} else {
// Обработка файла
printf("Thread ID: %lu, Path: %s, Size: %ld\n", pthread_self(), full_path, file_stat.st_size);
fprintf(output_file, "File: %s, Size: %ld\n", full_path, file_stat.st_size);
}
}
closedir(dir);
// Ожидание завершения всех дочерних потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
}
void process_directory(void arg) { char path = (char )arg; // Приводим аргумент к строке
// Открываем файл вывода для записи
FILE *output_file = fopen("output.txt", "a"); // Открываем файл в режиме добавления
if (output_file == NULL) {
handle_error("process_directory", "Error opening output file");
free(path);
return NULL;
}
list_files(path, output_file); // Вызов функции для обработки директории
fclose(output_file); // Закрываем файл вывода
free(path); // Освобождаем память
return NULL;
}
void handle_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void process_directory(void arg);
void process_directory(void arg); void handle_error(const char module_name, const char message); void list_files(const char path, FILE output_file);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s
const char *dir_path = argv[1];
const char *output_file_path = argv[2];
FILE *output_file = fopen(output_file_path, "w");
if (output_file == NULL) {
handle_error(argv[0], "Error opening output file");
return EXIT_FAILURE;
}
// Запускаем обработку директории
list_files(dir_path, output_file);
fclose(output_file);
return EXIT_SUCCESS;
}
void list_files(const char path, FILE output_file) { DIR *dir = opendir(path); if (dir == NULL) { handle_error("list_files", "Error opening directory"); return; }
struct dirent *entry;
pthread_t threads[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем '.' и '..'
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
struct stat file_stat;
if (stat(full_path, &file_stat) == -1) {
handle_error("list_files", "Error getting file status");
continue;
}
if (S_ISDIR(file_stat.st_mode)) {
// Создаем новый поток для обработки подкаталога
if (thread_count < MAX_THREADS) {
// Создаем новый поток
char *path_copy = strdup(full_path); // Копируем путь
if (pthread_create(&threads[thread_count++], NULL, process_directory, path_copy) != 0) {
handle_error("list_files", "Error creating thread");
free(path_copy);
}
} else {
// Ожидаем завершения одного из потоков
pthread_join(threads[--thread_count], NULL);
}
} else {
// Обработка файла
printf("Thread ID: %lu, Path: %s, Size: %ld\n", pthread_self(), full_path, file_stat.st_size);
fprintf(output_file, "File: %s, Size: %ld\n", full_path, file_stat.st_size);
}
}
closedir(dir);
// Ожидание завершения всех дочерних потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
}
void process_directory(void arg) { char path = (char )arg; // Приводим аргумент к строке
// Открываем файл вывода для записи
FILE *output_file = fopen("output.txt", "a"); // Открываем файл в режиме добавления
if (output_file == NULL) {
handle_error("process_directory", "Error opening output file");
free(path);
return NULL;
}
list_files(path, output_file); // Вызов функции для обработки директории
fclose(output_file); // Закрываем файл вывода
free(path); // Освобождаем память
return NULL;
}
void handle_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void handle_error(const char module_name, const char message); void list_files(const char path, FILE output_file);
// Определяем функцию process_directory сразу перед её использованием void process_directory(void arg) { char path = (char )arg; // Приводим аргумент к строке
// Открываем файл вывода для записи
FILE *output_file = fopen("output.txt", "a"); // Открываем файл в режиме добавления
if (output_file == NULL) {
handle_error("process_directory", "Error opening output file");
free(path);
return NULL;
}
list_files(path, output_file); // Вызов функции для обработки директории
fclose(output_file); // Закрываем файл вывода
free(path); // Освобождаем память
return NULL;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s
const char *dir_path = argv[1];
const char *output_file_path = argv[2];
FILE *output_file = fopen(output_file_path, "w");
if (output_file == NULL) {
handle_error(argv[0], "Error opening output file");
return EXIT_FAILURE;
}
// Запускаем обработку директории
list_files(dir_path, output_file);
fclose(output_file);
return EXIT_SUCCESS;
}
void list_files(const char path, FILE output_file) { DIR *dir = opendir(path); if (dir == NULL) { handle_error("list_files", "Error opening directory"); return; }
struct dirent *entry;
pthread_t threads[MAX_THREADS];
int thread_count = 0;
while ((entry = readdir(dir)) != NULL) {
// Пропускаем '.' и '..'
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char full_path[MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
struct stat file_stat;
if (stat(full_path, &file_stat) == -1) {
handle_error("list_files", "Error getting file status");
continue;
}
if (S_ISDIR(file_stat.st_mode)) {
// Создаем новый поток для обработки подкаталога
if (thread_count < MAX_THREADS) {
// Создаем новый поток
char *path_copy = strdup(full_path); // Копируем путь
if (pthread_create(&threads[thread_count++], NULL, process_directory, path_copy) != 0) {
handle_error("list_files", "Error creating thread");
free(path_copy);
}
} else {
// Ожидаем завершения одного из потоков
pthread_join(threads[--thread_count], NULL);
}
} else {
// Обработка файла
printf("Thread ID: %lu, Path: %s, Size: %ld\n", pthread_self(), full_path, file_stat.st_size);
fprintf(output_file, "File: %s, Size: %ld\n", full_path, file_stat.st_size);
}
}
closedir(dir);
// Ожидание завершения всех дочерних потоков
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
}
void handle_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
typedef struct { char path; FILE output_file; } ThreadData;
void calculate_directory_size(void arg) { ThreadData data = (ThreadData )arg; char path = data->path; FILE output_file = data->output_file;
// ... код для подсчета размера файлов в каталоге ...
// Пример вывода информации
fprintf(output_file, "Directory: %s\n", path);
// ... вывод количества файлов, суммарного размера и имени самого большого файла ...
pthread_exit(NULL);
}
int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "./%s: Error: Not enough arguments.\n", argv[0]); return 1; }
char *directory = argv[1];
char *output_filename = argv[2];
FILE *output_file = fopen(output_filename, "w");
if (!output_file) {
fprintf(stderr, "./%s: Error opening output file: %s\n", argv[0], output_filename);
return 1;
}
// ... код для создания потоков и управления ими ...
// Пример создания потока
pthread_t threads[MAX_THREADS];
ThreadData thread_data[MAX_THREADS];
int thread_count = 0;
// ... код для обхода подкаталогов и создания потоков ...
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
fclose(output_file);
return 0;
}
void process_directory(const char dir_path, FILE output_file) { DIR dir; struct dirent entry; struct stat file_stat; char full_path[1024]; long total_size = 0; int file_count = 0; char largest_file[1024] = ""; long largest_size = 0;
if ((dir = opendir(dir_path)) == NULL) {
fprintf(stderr, "%s: Error opening directory: %s\n", dir_path, dir_path);
return;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.') continue; // Пропускаем скрытые файлы
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
if (stat(full_path, &file_stat) == -1) {
fprintf(stderr, "%s: Error getting file stats: %s\n", dir_path, full_path);
continue;
}
if (S_ISREG(file_stat.st_mode)) { // Если это файл
total_size += file_stat.st_size;
file_count++;
if (file_stat.st_size > largest_size) {
largest_size = file_stat.st_size;
strcpy(largest_file, entry->d_name);
}
printf("PID: %d, Path: %s, File: %s, Size: %ld\n", getpid(), dir_path, entry->d_name, file_stat.st_size);
} else if (S_ISDIR(file_stat.st_mode)) { // Если это подкаталог
// Создаем новый процесс для обработки подкаталога
pid_t pid = fork();
if (pid == 0) { // Дочерний процесс
process_directory(full_path, output_file);
exit(0);
} else if (pid < 0) {
fprintf(stderr, "%s: Error creating process for directory: %s\n", dir_path, full_path);
}
}
}
closedir(dir);
// Записываем результаты в файл
fprintf(output_file, "Directory: %s, File Count: %d, Total Size: %ld, Largest File: %s\n",
dir_path, file_count, total_size, largest_file[0] ? largest_file : "None");
}
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s
const char *directory = argv[1];
const char *output_file_name = argv[2];
int max_processes = atoi(argv[3]);
FILE *output_file = fopen(output_file_name, "w");
if (!output_file) {
fprintf(stderr, "%s: Error opening output file: %s\n", argv[0], output_file_name);
return EXIT_FAILURE;
}
// Обработка корневого каталога
process_directory(directory, output_file);
// Ожидание завершения всех дочерних процессов
while (wait(NULL) > 0);
fclose(output_file);
return EXIT_SUCCESS;
}
include
include
include
include
include <sys/stat.h>
include
include
define MAX_THREADS 6
typedef struct { char path[1024]; FILE *output_file; } ThreadArgs;
void print_error(const char module_name, const char message) { fprintf(stderr, "%s: %s\n", module_name, message); }
void process_directory(void args) { ThreadArgs threadArgs = (ThreadArgs )args; const char dir_path = threadArgs->path; FILE output_file = threadArgs->output_file;
}
int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s \n", argv[0]);
return 1;
}
}