从常规文件中读取:阻止或返回较少的数据?

时间:2016-05-05 04:20:21

标签: c io posix

read是否可以

  • 返回的数据少于请求的数据

从常规文件中读取时,不包括:

  • 请求的数据多于SSIZE_MAX
  • 超越EOF阅读
  • 信号中断

read(3)建议,除了上述条件之外,从常规文件read读取时,永远不会返回比请求的字节数更少的字节。

  

如果文件中剩余的字节数小于nbyte,如果read()请求被信号中断,或者文件是管道或FIFO或特殊文件,则返回的值可能小于nbyte可立即读取的字节数少于nbyte。

但是,this answer提出了一个假设,即如果内核希望优先考虑其他I / O,read可能返回的字节数少于请求的字节数。虽然是一个假设,但重点是在任何条件下都无法读取预期的返回数据。因此,即使上述三个条件(SSIZE_MAX,EOF,中断)不适用,也不会安全,在常规文件上使用read而不检查返回值:

// all blockable signals have been ignored
// 10 is guaranteed less than SSIZE_MAX
// file size is known, access is locked
if (read(fd_of_big_reg_file_with_zero_offset, buf, 10) < 0) {
    // so all we have to do is handle errors
}

此外,我从未经历过要阻止的常规文件的读取,但我认为在可恢复的I / O错误的情况下可能会发生错误,例如需要多次重读的坏块。

1 个答案:

答案 0 :(得分:4)

获取简短读取的一种方法(除了问题中提到的情况)是在读取过程中发生I / O错误。

想象一下,例如,您有一个大小为1024的常规文件,占用两个512字节的扇区。你不知道,第二个部门是坏的,无法阅读。打开文件并执行read(fd, buf, 1024)将返回512,并且不会设置errno。如果您尝试再次阅读 ,则会得到-1errno = EIO的返回值。

我可以使用设备映射器的error函数在Linux上测试它。

由于您的程序无法排除I / O错误的可能性,因此这意味着假设来自read的任何正返回值必须意味着您阅读请求的字节数。