open()和read()系统调用...程序没​​有执行

时间:2013-11-14 08:17:36

标签: c file unix pointers unistd.h

我正在尝试制作一个程序,使用所述系统调用将512个字节从1个文件复制到另一个文件(我可以制作一些缓冲区,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. 这些低级功能究竟是如何工作的?是否有一个指针随着每个系统调用而移动,比如说如果我们使用带有fwrite的FILE *文件,我们的*文件会自动递增,还是我们必须手动递增文件指针?如果是这样,我们将如何访问它,假设open()等从未指定文件指针,而只是文件ID?

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

2 个答案:

答案 0 :(得分:3)

您没有看到打印消息的原因是您没有刷新缓冲区。一旦程序完成,文本应该出现(这种情况从未发生过,为什么会这样,在trojanfoe的评论和paxdiablo的回答中解释)。只需在字符串末尾添加换行符即可查看。

您在读/写循环中出现严重错误。如果您读取 less 而不是请求的512字节,您仍然会写512个字节。

此外,当您在打开时检查错误时,您不知道哪个失败的open次呼叫。即使出现错误,您仍然可以继续执行该程序。

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

答案 1 :(得分:2)

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

至于为什么它会永远等待,你只会在错误时得到-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