【问题标题】:open() and read() system calls...program not executingopen() 和 read() 系统调用...程序未执行
【发布时间】:2013-11-27 04:02:03
【问题描述】:

我正在尝试制作一个程序,使用所述系统调用将 512 字节从一个文件复制到另一个文件(我可以制作几个缓冲区,memcpy() 然后 fwrite() 但我想练习 Unix 特定的低级 I/O)。这是代码的开头:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
     int src, dest, bytes_read;
     char tmp_buf[512];

     if (argc < 3)
        printf("Needs 2 arguments.");

     printf("And this message I for some reason don't see.... o_O");

     if ((src = open(argv[1], O_RDWR, 0)) == -1 || (dest = open(argv[2], O_CREAT, 0)) == -1)
         perror("Error");

     while ((bytes_read = read(src, tmp_buf, 512)) != -1)
         write(dest, tmp_buf, 512);

   return 0;
}

我知道我没有处理读取的文件大小不会是 512 的倍数的事实。但首先我真的需要弄清楚两件事:

  1. 为什么我的消息没有显示?也没有分段错误,所以我最终只能 C-c 退出程序

  2. 这些低级函数究竟是如何工作的?是否有一个指针随着每个系统调用而变化,比如如果我们使用 FILE *file 和 fwrite,我们的 *file 会自动递增,还是我们必须手动递增文件指针?如果是这样,假设 open() 等从不指定文件指针,而只指定文件 ID,我们将如何访问它?

任何帮助都会很棒。请。谢谢!

【问题讨论】:

    标签: c file unix pointers unistd.h


    【解决方案1】:

    您看不到该消息的原因是您处于行缓冲模式。只有在发现换行符时才会刷新。

    至于为什么它会永远等待,您只会在 错误时得到 -1。

    成功读取到文件末尾会给你一个 0 返回值。

    更好的循环应该是:

    int bytes_left = 512;
    while ((bytes_left > 0) {
        bytes_read = read(src, tmp_buf, bytes_left);
        if (bytes_read < 1) break;
        write(dest, tmp_buf, bytes_read);
        bytes_left -= bytes_read;
    }
    if (bytes_left < 0)
        ; // error of some sort
    

    【讨论】:

      【解决方案2】:

      您看不到打印消息的原因是您没有刷新缓冲区。但是,一旦程序完成,文本 should 就会出现(这永远不会发生,为什么会这样,在 trojanfoe 的评论和 paxdiablo 的回答中进行了解释)。只需在字符串末尾添加换行符即可查看它们。

      你在读/写循环中有一个严重的错误。如果您读取 少于 所请求的 512 字节,您仍将写入 512 字节。

      此外,虽然您确实在打开时检查错误,但您不知道 哪些 open 调用失败了。即使出现错误,您仍然可以继续执行程序。

      最后,这些函数非常简单:它们调用内核中的一个函数来为您处理所有事情。如果您读取 X 字节,则文件指针在调用完成后向前移动 X 字节。

      【讨论】:

      • 非常感谢。我将解决那些公开电话问题,我知道这是一个笨拙的举动。至于功能实现,谢谢你告诉我。我害怕它总是指向开始
      猜你喜欢
      • 2011-02-04
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 2022-06-15
      相关资源
      最近更新 更多