阅读目录

时间:2010-03-20 20:17:07

标签: c windows

我正在尝试解决K& R的运动;这是关于阅读目录。此任务取决于系统,因为它使用系统调用。在本书的例子中,作者说他们的例子是为V7和System V UNIX系统编写的,他们使用了头文件中的目录信息。 sys / dir.h>,如下所示:

#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'函数来检索目录条目,该条目由文件名和inode号组成。

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

我认为这在UNIX和Linux系统上运行良好,但我想要做的是修改它以便在Windows XP上运行。

Windows中有一些结构,比如'struct direct',所以我可以使用它 使用'read'函数,如果有什么是标题名称 定义

或者Windows可能需要完全不同的方法?

4 个答案:

答案 0 :(得分:2)

在Windows中没有类似的东西。如果要在Windows中枚举目录,则必须使用FindFirstFile / FindNextFile API。

答案 1 :(得分:1)

是的,这仅适用于Linux / Unix。但是,如果您只是在玩游戏,可以使用Cygwin在Windows上构建使用此Unix API的程序。

答案 2 :(得分:1)

boost::filesystem::directory_iterator提供了Windows FindFirstFile / FindNextFile API和POSIX readdir_r()API的可移植等效项。请参阅this tutorial

请注意,这是 C ++ 而不是普通的C.

答案 3 :(得分:1)

值得注意的是,您使用的是1978年的K& R 1st Edition,而不是第二版。第二版在本书的那一点有不同的结构等。

第一版的代码不再适用于许多类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()在目录文件描述符上。

或者您可以使用BillyONeal引用的本机Windows API,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);
}