从文件中读取N个字节,并使用read()和write()进行打印

时间:2018-10-24 17:54:12

标签: c linux

我正在尝试读取一个程序,该程序使用read()从文件中读取N个字节,并使用write()在STDOUT中打印它们。关键是,用户还可以指定块大小,默认情况下为1024,最多只能达到1048576。我必须将读取的内容存储在缓冲区中,但是该缓冲区的大小不能与我所用的字节大小相同必须阅读,因为否则,我可能会创建一个对于堆栈大小太大的缓冲区。因此,我创建了一个与块大小一样大的缓冲区,因此我只是读取直到缓冲区满,然后写入,然后再次读取到缓冲区的开头。

所有这一切的问题是,它绝对无法按预期工作,而且我敢肯定,必须有一种更简单的方法来实现此目的。

相关代码:

void run_hd_b (int b, int fd, int BSIZE){
    int res_read; //result from write
    int res_write; //result from read
    int read_bytes = 0;
    char buffer[BSIZE];
    int i = 0;

    int count = 0;
    if (b < BSIZE) count = b;
    else count = BSIZE;

    while (read_bytes < b && (res_read = read(fd, &buffer[i], count)) != 0){ 
        if (res_read == BSIZE){
            i = 0;
        }
        else i = res_read;

        read_bytes += res_read;
        while((res_write = write(1, buffer, res_read)) < res_read);
    }
}

1 个答案:

答案 0 :(得分:0)

下面是循环的修订版,可以编译(并且可能可以工作),并附带一些注释。

#include <assert.h>
#include <unistd.h>

void run_hd_n (int n, int fd, int BSIZE) {
  int res_read;
  char buffer[BSIZE];

  // can only get up to 1048576
  assert(BSIZE <= 1048576);

  for( int read_bytes=0; read_bytes < n; read_bytes += res_read ) {
    if( (res_read = read(fd, buffer, BSIZE)) < BSIZE ) { 
      if( res_read == 0 ) return; // EOF or error
    }
    if( write(STDOUT_FILENO, buffer, res_read) < res_read ) return;
  }
}
  • 我不合常规将b更改为n
  • 贴近标准。 (2)和(2)占用size_t,而不是int。如果用n == -1调用,您的程序会如何反应?
  • 如果您有已知的强制约束,请将其包含在某个位置。您声明了BSIZE的最大尺寸;我使用assert来实施它。
  • 我无法确定您的问题是关于分配空间还是复制数据。我选择解决后者。
  • 读取的内容小于缓冲区的全部大小,这不是错误。无需将count放在putz中。只需阅读,看看是否有任何东西。
  • 您已使用返回类型void编写了一个I / O函数。呼叫者将如何了解发生了什么?我将返回res_read并让呼叫者测试他是否按要求阅读了太多内容,否则请咨询errno