Чтение каталога - PullRequest
       9

Чтение каталога

3 голосов
/ 20 марта 2010

Я пытаюсь решить упражнение из K & R; это о чтении каталогов. Эта задача зависит от системы, потому что она использует системные вызовы. В примере книги авторы говорят, что их пример написан для систем Версии 7 и System V UNIX и что они использовали информацию каталога в заголовке , который выглядит следующим образом:

#ifndef DIRSIZ
#define DIRSIZ 14
#endif
struct direct {    /* directory entry */
    ino_t d_ino;           /* inode number */
    char d_name[DIRSIZ];   /* long name does not have '\0' */
};

В этой системе они используют «struct direct» в сочетании с функцией «read» для извлечения записи каталога, состоящей из имени файла и номера индекса.

.....
struct direct dirbuf;    /* local directory structure */
while(read(dp->fd, (char *) &dirbuf, sizeof(dirbuf)
               == sizeof(dirbuf) {
    .....
}
.....

Полагаю, это нормально работает в системах UNIX и Linux, но я хочу изменить это, чтобы оно работало в Windows XP.

Есть ли в Windows какая-то структура, такая как "struct direct", чтобы я мог ее использовать с функцией «чтения» и, если есть, что является именем заголовка, где он находится определен

А может, для Windows нужен совершенно другой подход?

Ответы [ 4 ]

2 голосов
/ 20 марта 2010

Нет ничего подобного в Windows. Если вы хотите перечислить каталог в Windows, вы должны использовать API FindFirstFile / FindNextFile .

1 голос
/ 22 марта 2010

Интересно отметить, что вы используете K & R 1st Edition 1978 года, а не второе издание. Второе издание имеет различные структуры и т. Д. На тот момент в книге.

Этот код из первого издания больше не работает на многих Unix-подобных системах. Очень мало машин Unix осталось с файловыми системами, которые ограничивают имена файлов до 14-символьного ограничения, и этот код работает только в этих системах. В частности, он не работает на MacOS X (10.6.2) или Solaris (10) или Linux (SuSE Linux Enterprise Edition 10, ядро ​​2.6.16.60-0.21-smp). С тестовым кодом, показанным ниже, результат:

read failed: (21: Is a directory)

Текущие выпуски POSIX явно разрешают реализации ограничивать то, что вы можете делать с файловым дескриптором, открытым в каталоге. По сути, он может использоваться в системных вызовах 'fchdir()' и, возможно, нескольких родственниках, но это все.

Чтобы прочитать содержимое каталога, вы должны использовать семейство функций opendir(), а затем readdir() и т. Д. Второе издание K & R продолжается используйте эти системные вызовы вместо open() и read() и т. д.

В целом, неудивительно, что код более 30 лет назад работает не совсем так, как раньше.


В Windows вы можете использовать подсистему POSIX или ее эмуляцию, такую ​​как Cygwin или MingW, и в любом случае вам придется использовать семейство вызовов функций opendir() и readdir(), а не прямые open() и read() в дескрипторе файла каталога.

Или вы можете использовать собственный Windows API, на который ссылается BillyONeal, FindFirstFile и родственников.


Тестовый код:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

int main()
{
    int fd = open(".", O_RDONLY);
    if (fd != -1)
    {
        char buffer[256];
        ssize_t n = read(fd, buffer, sizeof(buffer));
        if (n < 0)
        {
            int errnum = errno;
            printf("read failed: (%d: %s)\n", errnum, strerror(errnum));
        }
        else
            printf("read OK: %d bytes (%s)\n", (int)n, buffer);
        close(fd);
    }
    return(0);
}
1 голос
/ 21 марта 2010

boost::filesystem::directory_iterator предоставляет переносимый эквивалент API-интерфейса Windows FindFirstFile / FindNextFile и POSIX readdir_r (). См. этот урок .

Обратите внимание, что это C ++ не просто C.

1 голос
/ 20 марта 2010

Да, это работает только в Linux / Unix. Однако, если вы просто играете вокруг, вы можете использовать Cygwin для создания программ под Windows, использующих этот Unix API.

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