Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include <pthread.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdbool.h>
- #include <sys/wait.h>
- #include <errno.h>
- #include <limits.h>
- typedef struct dirent DIRENT;
- typedef struct stat STAT;
- //cтруктура для создания потока
- typedef struct
- {
- const char *fullPath;
- const char *fileName;
- int outputFile;
- const char* stringForSearch;
- } ThreadArgs;
- //прототипы
- void searchStringInFile(const char *filePath, const char *fileName, const int outputFile, const char* stringForSearch);
- void *threadFuncForSearch(void *args);
- void searchInDirectory(const char *dirToSearch, const char *stringForSearch, const int outputFile, int maxThreads, pthread_t *threadIDs, int *threadCount);
- void printFileStats(const int outputFile, const char *fullPath, const char *fileName, const int bytesChecked, const unsigned isFound);
- void printTaskInfo();
- void searchStringInFile(const char *filePath, const char *fileName, const int outputFile, const char* stringForSearch)
- {
- FILE *fileForCheckPointer;
- if ((fileForCheckPointer = fopen(filePath, "rb")) == NULL) // файл не открылся для чтения
- {
- fprintf(stderr, "Не удалось прочитать данные в файле %s.\n", fileName);
- return;
- }
- char tempChar;
- int byteCounter = 0;
- unsigned isFound = 0;
- while (!feof(fileForCheckPointer))
- {
- byteCounter++;
- tempChar = getc(fileForCheckPointer);
- if (tempChar == stringForSearch[0]) // если текущий выбранный символ в файле совпал с первым символом проверочной строки
- {
- int i = 1;
- isFound = 1;
- while (stringForSearch[i] != '\0' && isFound)
- { // пока строка не кончается и сравниваемые символы равны
- isFound = stringForSearch[i] == getc(fileForCheckPointer);
- i++;
- }
- }
- }
- printFileStats(outputFile, filePath, fileName, byteCounter, isFound);
- fclose(fileForCheckPointer);
- }
- void *threadFuncForSearch(void *args)
- {
- ThreadArgs *threadArgs = (ThreadArgs *)args;
- const char *filePath = threadArgs->fullPath;
- const char *name = threadArgs->fileName;
- const int outputFile = threadArgs->outputFile;
- const char* stringForSearch = threadArgs->stringForSearch;
- printf("\nID нового потока: %ld\n", pthread_self());
- searchStringInFile(filePath, name, outputFile, stringForSearch);
- free(args);
- return NULL;
- }
- void searchInDirectory(const char *dirToSearch, const char *stringForSearch, const int outputFile, int maxThreads, pthread_t *threadIDs, int *threadCount)
- {
- DIR *dir = opendir(dirToSearch);
- if (dir == NULL) // если каталог не удалось открыть
- {
- perror("Ошибка при открытии каталога!");
- }
- DIRENT *entry;
- while ((entry = readdir(dir)) != NULL)
- {
- char fullPath[PATH_MAX];
- snprintf(fullPath, PATH_MAX, "%s/%s", dirToSearch, entry->d_name);
- STAT buffer;
- stat(fullPath, &buffer);
- if (S_ISREG(buffer.st_mode))
- {
- ThreadArgs *threadArgs = (ThreadArgs *)malloc(sizeof(ThreadArgs));
- threadArgs->fullPath = strdup(fullPath);
- threadArgs->fileName = strdup(entry->d_name);
- threadArgs->outputFile = outputFile;
- threadArgs->stringForSearch = stringForSearch;
- pthread_create(&threadIDs[*threadCount], NULL, threadFuncForSearch, (void *)threadArgs);
- (*threadCount)++;
- if (*threadCount >= maxThreads)
- {
- for (int i = 0; i < maxThreads; i++)
- {
- pthread_join(threadIDs[i], NULL);
- }
- *threadCount = 0;
- }
- }
- }
- closedir(dir);
- for (int i = 0; i < *threadCount; i++)
- {
- pthread_join(threadIDs[i], NULL);
- }
- }
- /* процедуры для вывода */
- void printFileStats(const int outputFile, const char *fullPath, const char *fileName, const int bytesChecked, const unsigned isFound)
- {
- printf("\n\tПуть: %s\n", fullPath);
- printf("\tИмя файла: %s\n", fileName);
- printf("\tКоличество просмотренных байт: %d\n", bytesChecked);
- printf("\tНайдена ли строка: %s\n", ((isFound) ? "Да" : "Нет"));
- dprintf(outputFile, "\n\tПуть: %s\n", fullPath);
- dprintf(outputFile, "\tИмя файла: %s\n", fileName);
- dprintf(outputFile, "\tКоличество просмотренных байт: %d\n", bytesChecked);
- dprintf(outputFile, "\tНайдена ли строка: %s\n\n", ((isFound) ? "Да" : "Нет"));
- }
- void printTaskInfo()
- {
- printf("\n\tДанная программа ищет в заданном каталоге все файлы,\n\t\t которые содержат заданную строку.\n\tРезультаты выводятся на консоль и в указанный файл.\n\n");
- }
- /* процедуры для вывода */
- int main(int argc, char *argv[])
- {
- const int NUM_OF_ARGS = 5;
- if (argc != NUM_OF_ARGS)
- {
- fprintf(stderr, "Неверный ввод!\nФормат ввода: %s <заданный каталог> <строка для поиска> <файл вывода> <кол-во процессов>\n", argv[0]);
- fprintf(stderr, "Повторите запуск программы!\n");
- return EXIT_FAILURE;
- }
- char *directoryPath = argv[1];
- char *stringForSearch = argv[2];
- const int outputFile = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
- if (outputFile == -1)
- {
- perror("Ошибка при открытии файла для записи!");
- return EXIT_FAILURE;
- }
- const int maxThreads = atoi(argv[4]);
- pthread_t threadIDs[maxThreads];
- int threadCount = 0;
- printTaskInfo();
- searchInDirectory(directoryPath, stringForSearch, outputFile, maxThreads, threadIDs, &threadCount);
- close(outputFile);
- printf("\n\t\tВывод в файл успешно завершен!\n");
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement