c - 我无法弄清楚c中的系统调用 "read"函数。 (K&R c语言书)

标签 c unix filesystems system-calls

我是 C 新手,这甚至是我在“stackoverflow.com”中要问的第一个问题 如果我做了一些不愉快的事情,请纠正我:)

所以,我想了解的是“读取功能”的真正过程是什么。 让我在解释我正在实验的内容时详细说明我的问题。 我的小程序的基本概念是将文件复制到屏幕中。

#include <stdio.h>
#include <fcntl.h>
#define BUF_SIZE 1000

int main(int argc,char *argv[])
{ 
        int fd, n;
        char buf[BUF_SIZE];
        char *name;
        name = argv[1];

        fd = open(name, O_RDWR, 0);

//------------whith while loop -----------------------
        //while( (n = read( fd, buf, BUF_SIZE)) > 0 )
        //       {
        //              printf("?");
        //
        //              write(1, buf, n);
        //              printf("??");
        //       }

// ------------without while loop ----------------

              n = read( fd, buf, BUF_SIZE);
                printf("?");
                write(1, buf, n);
                printf("??");

        return 0;
}

首先,(1)我的问题是“为什么我需要 while 循环来读取()?

我的理解是,在我调用系统调用“read()”之后(我不确定它是真正的系统调用还是只是 C 库提供的函数,它将调用真正的系统调用), 它现在获取 buf[] 和 BUF_SIZE 来填充,并且它发生在一次调用中。但话又说回来,应该有一个放置 while 循环的理由..

但是两者的结果是相同的,显示的文件内容完全相同。

第二,(2)我的问题是,如果系统调用“read”被调用几次直到文件末尾,那么在循环调用“write function”时可以进入多少次(即为什么我放 printf("?") )。

但是结果中风... 它忽略了我的 printf 函数,无论它是在“write”之前还是之后调用。

我认为我缺少一个非常大的概念..我希望有人能真正帮助我:) 先感谢您。

最佳答案

好的,一步一步来。您调用的 read 函数实际上是一个低级系统调用的包装器,可能称为 sys_read。通常,C 标准库为所有系统调用提供包装器。

为什么要使用 while 循环?

read 函数返回该函数读取的字节数。这并不需要文件包含的所有字节。您需要一个 while 循环来继续读取文件,以便能够完全处理它。如果两个版本都有效(有循环和没有循环),可能(最肯定)是因为文件很小,并且您能够将其完全存储在数组中,但是 1GB 文件又如何呢?

write 函数的行为或多或少相同,有时您也需要一个 while 循环来完全转储文件中的缓冲区。

为什么 printf 不打印?

printf 函数通常在将数据转储到控制台之前缓冲数据。通常,它会等到看到行尾字符后再转储它,因此如果您将代码更改为: printf("??\n"); 您可能会看到它在屏幕上。

还有一件事,当然还有更多关于这些的技术内容(很多),所以如果你真的想了解 read 函数(以及任何其他 Unix系统调用或 C 库函数)您可以查阅手册第 2 页和第 3 页(第 2 页用于系统调用,第 3 页用于库函数)。例如,read 记录在 read(2) 中。 。如果您想更深入地了解,请获取源代码,看看真正是如何工作的:)

希望这有帮助!

关于c - 我无法弄清楚c中的系统调用 "read"函数。 (K&R c语言书),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22289472/

相关文章:

c - 如何在c中将文件中的单词与数字分开

linux - 是否可以为 Linux 终端即时生成字形?

linux - 嵌套 EPOLL FD

c - 文件中的垃圾字符

c - C中的递归后序遍历和sprintf

几个线程的临界区

c - 在c中克隆avl树时出现总线错误

linux - 模拟用户输入以使用不同参数多次调用脚本

php - 如何通过php网页执行crontab -l? Linux权限

jquery - 从用户的本地系统获取文件的属性(上次修改日期)