【问题标题】:Linux/ Open directory as a fileLinux/ 以文件形式打开目录
【发布时间】:2014-01-28 11:57:36
【问题描述】:

我一直在阅读 Brian Kernighan 和 Dennis Ritchie - The C Programming Language 和第 8.6 章是关于 UNIX OS 下的目录列表。他们说一切甚至目录都是一个文件。这意味着我应该能够将目录作为文件打开?我已经使用 stdio 函数尝试过它,但它没有用。现在,我正在尝试使用 UNIX 系统功能。当然,我用的不是 UNIX,我用的是 Ubuntu linux。这是我的代码:

#include <syscall.h>
#include <fcntl.h>

int main(int argn, char* argv[]) {
    int fd;
    if (argn!=1) fd=open(argv[1],O_RDONLY,0);
    else fd=open(".",O_RDONLY,0);
    if (fd==-1) return -1;

    char buf[1024];
    int n;
    while ((n=read(fd,buf,1024))>0)
        write(1,buf,n);

    close (fd);
    return 0;
}

即使 argn 为 1(无参数)并且我正在尝试读取当前目录,这也不会写入任何内容。 有什么想法/解释吗? :)

【问题讨论】:

  • 最好使用argc 而不是argn - 通常使用它可以减少混淆。
  • Kernighan 和 Ritchie 确实断言一切都是文件。但是,本书稍后还指出opendirreaddirclosedir 旨在打开、读取和关闭Dirent 结构,它基本上是目录“文件”的可移植描述。然而,文件系统在 unix 变体之间有所不同,这或许可以解释为什么系统坚持对目录使用这些特殊方法。
  • 是的,我看到他们已经实现了 Dirent 结构,但他们是这样做的,所以很混乱。感谢您对文件系统的解释。

标签: c linux unix filesystems gnu


【解决方案1】:

文件也称为regular files,以区别于special files

目录或不是regular file。最常见的special file 是目录。目录文件的布局由使用的文件系统定义。

所以使用opendir打开目录。

【讨论】:

  • 谢谢!这是@Achim 之前的回答和评论,它解释了有关文件系统依赖性、特殊文件和可能发生的错误的全部内容。 :)
【解决方案2】:

Nachiket 的回答是正确的(确实是 sujin),但他们没有解开为什么 open 有效而不是 read 的谜团。出于好奇,我对给定的代码进行了一些更改,以了解到底发生了什么。

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

int main(int argc, char* argv[]) {
    int fd = -1;
    if (argc!=1) fd=open(argv[1],O_RDONLY,0);
    else fd=open(".",O_RDONLY,0);
    if (fd < 0){
      perror("file open");
      printf("error on open = %d", errno);
      return -1;
    }
    printf("file descriptor is %d\n", fd);

    char buf[1024];
    int n;
    if ((n=read(fd,buf,1024))>0){
        write(1,buf,n);
    }
    else {
      printf("n = %d\n", n);
      if (n < 0) {
        printf("read failure %d\n", errno);
        perror("cannot read");
      }
    }
    close (fd);
    return 0;
}

编译运行结果:

file descriptor is 3
n = -1
read failure 21
cannot read: Is a directory

这样就解决了,虽然我预计 open 会失败,因为打开目录的正确系统函数是 opendir()

【讨论】:

  • 谢谢,这真的很有帮助。我看到 fd 是 3,但我没有检查读取的返回表单。 :)
  • 在目录上使用open() 有时对于使用文件描述符的调用很有用,例如用于fchmod()fchdir()fdopendir()。不过,打开目录的 fd 也可以使用 dirfd()DIR * 中拉出。
  • 最佳答案在这里,基本上 linux 处理目录的方式与 unix 不同。
【解决方案3】:

虽然 unix 中的所有内容都是文件(也是目录),但文件类型仍然是 unix 中存在的概念,适用于所有文件。 有常规文件、目录等文件类型,并且每种文件类型都允许/存在某些操作和功能。

在您的情况下, readdir 适用于读取目录的内容。

【讨论】:

    【解决方案4】:

    如果您想查看目录中的文件,您必须使用opendirreaddir 函数。

    【讨论】:

      【解决方案5】:

      K&R 对于原始 UNIX 是正确的。我记得当 UNIX 文件系统的文件名长度限制为 14 个字符时,我曾这样做过。 opendir(), readdir(), ...这些事情发生在更长的文件名变得普遍的时候(大约在 1990 年?)

      【讨论】:

        猜你喜欢
        • 2011-03-28
        • 2015-09-27
        • 2017-10-26
        • 2014-11-20
        • 2023-03-09
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多