从常规文件读取:阻止还是返回较少的数据? [英] read from regular file: block or return less data?

查看:36
本文介绍了从常规文件读取:阻止还是返回较少的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

read 是否可以

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

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

when reading from a regular file, excluding:

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

read(3)建议,除上述条件外,从常规文件读取时 read 绝不会返回比请求的字节少的字节.

read(3) suggests that, excluding the above conditions, when reading from a regular file read will never return fewer bytes than requested.

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

The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal, or if the file is a pipe or FIFO or special file and has fewer than nbyte bytes immediately available for reading.

但是,此答案提出了一种假设,其中 read 返回的字节数可能少于请求的字节数.如果内核希望优先处理其他I/O.尽管是假设的,但要点是,在任何条件下都无法读取预期返回的数据是否与请求的数据一样多.因此,即使以上三个条件(SSIZE_MAX,EOF,中断)不适用,也不会在不检查返回值的情况下对常规文件使用 read ,这永远是不安全的:

However, this answer suggests a hypothetical in which read may return fewer bytes than requested if the kernel wishes to prioritize other I/O. While a hypothetical, the point is that under no conditions can read be expected return exactly as much data as requested. So it is never safe, even if the above three conditions (SSIZE_MAX, EOF, interrupt) do not apply, to use read on a regular file without checking the return value:

// 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错误(例如需要多次重读的坏块)的情况下,这是有可能的.

Furthermore, I have never experienced a read on a regular file to block, but I assume it is possible in the event of a recoverable I/O error, such as a bad block requiring multiple rereads.

推荐答案

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

One way to get a short read (in addition to the cases mentioned in your question) is if an I/O error occurs in the middle of a read.

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

Imagine for example that you have a regular file of size 1024, occupying two 512-byte sectors. Unbeknown to you, the second sector is bad and cannot be read. Opening the file and doing read(fd, buf, 1024) will return 512 and will not set errno. If you try to read again, you get a return value of -1 and errno = EIO.

我能够使用设备映射器的 error 函数在Linux上进行测试.

I was able to test this on Linux using the device mapper's error function.

由于您的程序无法做任何事情来排除I/O错误的可能性,因此这意味着从 read 返回的任何正返回值都必须表示您是绝对不安全的.读取所需的字节数.

Since there isn't anything your program can do to rule out the possibility of I/O errors, this implies that it is never safe to assume that any positive return value from read must mean you read as many bytes as requested.

这篇关于从常规文件读取:阻止还是返回较少的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆