提问人:Kouros 提问时间:6/16/2013 更新时间:9/13/2023 访问量:3454
Linux C 读取目录
Linux C read a directory
问:
您好,我想读取和写入目录,就像读取和写入文件一样。我总是使用 、 和 函数,这意味着我使用描述符。但是在目录上执行此操作不起作用,调用有效,但返回 -1 并且是 EISDIR。我是否被迫使用流来读取目录?open
read
write
close
open
read
errno
答:
0赞
markmb
6/16/2013
#1
我在Stack Overflow(如何使用C或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 );
}
}
3赞
caf
6/16/2013
#2
不能在目录上使用 and 系统调用。相反,/ 系统调用用于读取目录。根本无法直接写入目录。read()
write()
getdents()
getdents64()
此外,glibc 没有为 / 系统调用提供包装器 - 而是提供符合 POSIX 的函数,该函数是使用这些系统调用实现的。大多数程序应该使用 ,但也可以直接使用 调用系统调用。getdents()
getdents64()
readdir()
readdir()
syscall()
1赞
Hosein Rahnama
9/13/2023
#3
正如@caf指出的,您应该用于此目的。实际上,人们使用序列 , 来读取目录文件。此外,目录是只读的,不能写入。但是,如果您对使用系统调用读取目录感到好奇,这里有一个没有错误检查的最小示例。在这里,该函数采用与目录对应的文件描述符,并在每次调用时返回一个目录条目。目录名称可以作为命令行参数传递。默认行为打印当前工作目录的内容。你可以在这里或这里阅读更多关于的信息。readdir
opendir
readdir
closedir
getdents
read_dirent
getdents
#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;
}
评论