Глоб с каталогом, предоставленным пользователем? - PullRequest
2 голосов
/ 06 мая 2011

Я пишу программу, которая должна искать в каталоге, который предоставляет пользователь, чтобы найти все файлы в указанном каталоге, к которым был произведен доступ, которые были изменены или изменены в течение дня с заданным временем. У меня две определенные проблемы и, возможно, еще одна.

Первая проблема в том, что я могу заставить программу выполнять только поверхностный поиск, она не просматривает никакие подкаталоги. Я уверен, что это связано с тем, что я объединяю с буфером каталога (сейчас это . ). Вторая проблема заключается в том, что он не ищет все файлы, хотя и просматривает большинство из них - хотя я думаю, что это возвращает нас к первой проблеме. Третья «проблема» заключается в том, что когда я проверяю время доступа каждого файла, создается впечатление, что они все одинаковые (хотя у меня нет этой проблемы с измененным / измененным временем). Я работаю на Ubuntu через VM, если это может повлиять на время доступа.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <glob.h>

/* Function that checks if specified file was accessed, modified, or
changed within a day of the specified time.                 */
void checkFile(long long time, char * fileName) {
struct stat *s;
time_t accessTime;
time_t modTime;
time_t changeTime;
s = malloc(sizeof(struct stat));
if(stat(fileName,s) == 0) {
    accessTime = s->st_atime;
    modTime = s->st_mtime;      
    changeTime = s->st_ctime;
    if((time - accessTime) <= 86400 && (time - accessTime) >= -86400)
        printf("%s\n",fileName);
    else if((time - modTime) <= 86400 && (time - modTime) >= -86400)
        printf("%s\n",fileName);
    else if((time - changeTime) <= 86400 && (time - changeTime) >= -86400)
        printf("%s\n",fileName);
}
free(s);
}

void searchDirectory(long long time, glob_t globbuf) {
if(globbuf.gl_pathc == 0)
    printf("there were no matching files");
else {
    int i;
    for(i = 0; i < globbuf.gl_pathc; i++)
        checkFile(time,globbuf.gl_pathv[i]);
}
}

int main(int argc, char** argv) {
    long long time = atol(argv[1]);
    char * buf = argv[2];
    strcat(buf,"*.*");
    glob_t globbuf;
    glob(buf, 0, NULL, &globbuf);
    searchDirectory(time,globbuf);
    globfree(&globbuf);
    return 0;
}

Спасибо за ваше время!

1 Ответ

1 голос
/ 06 мая 2011

Вы не должны

cat(buf, "*.*");

..., поскольку «buf» - это указатель на строку, предоставляемую операционной системой - вы не знаете, достаточно ли этого буфера, чтобы вместить дополнительный текст, который выдобавляем.Вы можете выделить большой буфер, скопировать в него содержимое argv[2], а затем добавить "*.*", но для полной безопасности вы должны определить длину argv[2] и убедиться, что ваш буфер достаточно большой.

Вы можете использовать st_mode член структуры struct stat, чтобы определить, является ли файл каталогом (проверьте, равен ли он S_IFDIR).Если это так, вы можете сделать его текущим каталогом, и, как предложил jonsca, снова вызвать вашу функцию searchDirectory.Но при использовании рекурсии вы обычно хотите убедиться, что у вас есть ограничение на глубину рекурсии, или вы можете переполнить стек.Это своего рода «поиск в глубину».Решение, которое я предпочитаю, состоит в том, чтобы выполнить «поиск в ширину» с использованием очереди: в основном поместите свой первый глобус в начало списка, затем несколько раз уберите первый элемент из этого списка и выполните поиск, добавляя новые каталоги в конец списка.составляйте список по мере продвижения, пока список не станет пустым.

Оценивая подобные программы, учителя любят начислять дополнительные баллы тем, кто не набирает слишком много очков:)

PS IЯ предполагаю, что проблема времени доступа связана с несовместимостью виртуальных машин / файловой системы / etc, а не с вашей ошибкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...