你好,我想读和写一个目录就像阅读和写文件。我总是使用open、read、write和close函数,这意味着我使用描述符。但是在目录上这样做不起作用,open调用起作用,但是read返回-1,而errno是EISK。我是否被迫使用流来读取目录?
open
read
write
close
errno
zazmityj1#
read()和write()系统调用不能用于目录。相反,getdents()/getdents64()系统调用用于读取目录。目录根本不能直接写入。但是,glibc并没有为getdents()/getdents64()系统调用提供 Package 器,而是提供了符合POSIX的readdir()函数,该函数使用这些系统调用实现。大多数程序应该使用readdir(),但也可以直接使用syscall()调用系统调用。
read()
write()
getdents()
getdents64()
readdir()
syscall()
jum4pzuy2#
我在Stack Overflow(How can I get the list of files in a directory using C or C++?)中找到了这段代码,这对我理解它的工作原理有很大帮助:
#include <dirent.h> #include <stdio.h> #include <string.h> int main(){ DIR* dirFile = opendir( "." ); struct dirent* hFile; if ( dirFile ) { while (( hFile = readdir( dirFile )) != NULL ) { if ( !strcmp( hFile->d_name, "." )) continue; if ( !strcmp( hFile->d_name, ".." )) continue; // in linux hidden files all start with '.' if ( gIgnoreHidden && ( hFile->d_name[0] == '.' )) continue; // dirFile.name is the name of the file. Do whatever string comparison // you want here. Something like: if ( strstr( hFile->d_name, ".c" )) printf( "found an .txt file: %s", hFile->d_name ); } closedir( dirFile ); } }
fiei3ece3#
正如@caf所指出的,您应该使用readdir来实现此目的。实际上,使用opendir、readdir、closedir的序列来阅读目录文件。但是,目录是只读的,不能写入。但是,如果您对使用getdents * 系统调用 * 读取目录感到好奇,这里有一个没有错误检查的最小示例。在这里,函数read_dirent获取与目录对应的文件描述符,并在每次调用时返回一个目录条目。目录名可以作为命令行参数传递。默认行为打印当前工作目录的内容。您可以在here或here中阅读有关getdents的更多信息。
readdir
opendir
closedir
getdents
read_dirent
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/syscall.h> #define BUF_SIZE 1024 typedef struct linux_dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[]; } LinuxDirEnt; LinuxDirEnt *read_dirent(int fd); int main(int argc, char *argv[]) { int fd; LinuxDirEnt *d; fd = open(argc > 1 ? argv[1] : ".", O_RDONLY); printf("inode# d_reclen d_name\n"); while(d = read_dirent(fd)) printf("%8ld %4d %s\n", d->d_ino, d->d_reclen, d->d_name); exit(EXIT_SUCCESS); } LinuxDirEnt *read_dirent(int fd) { static int nread = 0; static int bpos = 0; static char buf[BUF_SIZE]; static LinuxDirEnt *d; if (nread == 0) { nread = syscall(SYS_getdents, fd, buf, BUF_SIZE); if (nread == 0) return NULL; bpos = 0; } else bpos += d->d_reclen; d = (LinuxDirEnt *)(buf + bpos); nread -= d->d_reclen; return d; }
3条答案
按热度按时间zazmityj1#
read()
和write()
系统调用不能用于目录。相反,getdents()
/getdents64()
系统调用用于读取目录。目录根本不能直接写入。但是,glibc并没有为
getdents()
/getdents64()
系统调用提供 Package 器,而是提供了符合POSIX的readdir()
函数,该函数使用这些系统调用实现。大多数程序应该使用readdir()
,但也可以直接使用syscall()
调用系统调用。jum4pzuy2#
我在Stack Overflow(How can I get the list of files in a directory using C or C++?)中找到了这段代码,这对我理解它的工作原理有很大帮助:
fiei3ece3#
正如@caf所指出的,您应该使用
readdir
来实现此目的。实际上,使用opendir
、readdir
、closedir
的序列来阅读目录文件。但是,目录是只读的,不能写入。但是,如果您对使用getdents
* 系统调用 * 读取目录感到好奇,这里有一个没有错误检查的最小示例。在这里,函数read_dirent
获取与目录对应的文件描述符,并在每次调用时返回一个目录条目。目录名可以作为命令行参数传递。默认行为打印当前工作目录的内容。您可以在here或here中阅读有关getdents
的更多信息。