从常规文件中读取:块或 return 更少的数据?
read from regular file: block or return less data?
有没有可能read
到
- 块
- return 比请求的数据少
从常规文件读取时,不包括:
- 请求比 SSIZE_MAX
更多的数据
- 阅读超过 EOF
- 信号中断
read(3)
建议,排除上述条件,从常规文件读取时 read
永远不会 return 比请求的字节少。
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.
但是,this answer 提出了一个假设,如果内核希望优先考虑其他 I/O,read
可能 return 字节数少于请求的字节数。虽然是假设,但关键是在任何情况下都无法读取 return 所请求的数据。因此,即使上述三个条件(SSIZE_MAX、EOF、中断)不适用,在不检查 return 值的情况下对常规文件使用 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 错误(例如需要多次重新读取的坏块)的情况下是可能的。
获得简短阅读的一种方法(除了您问题中提到的情况之外)是在阅读过程中是否出现 I/O 错误。
假设您有一个大小为 1024 的常规文件,占用两个 512 字节的扇区。你不知道的是,第二扇区坏了,无法读取。打开文件并执行 read(fd, buf, 1024)
将 return 512 而不会设置 errno
。如果您再次尝试读取 ,您会得到 return 值 -1
和 errno = EIO
.
我能够使用设备映射器的 error
功能在 Linux 上对此进行测试。
由于您的程序无法执行任何操作来排除 I/O 错误的可能性,这意味着假设 [=15] 中的任何正 return 值都是不安全的=] 必须表示您读取了请求的字节数。
有没有可能read
到
- 块
- return 比请求的数据少
从常规文件读取时,不包括:
- 请求比 SSIZE_MAX 更多的数据
- 阅读超过 EOF
- 信号中断
read(3)
建议,排除上述条件,从常规文件读取时 read
永远不会 return 比请求的字节少。
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.
但是,this answer 提出了一个假设,如果内核希望优先考虑其他 I/O,read
可能 return 字节数少于请求的字节数。虽然是假设,但关键是在任何情况下都无法读取 return 所请求的数据。因此,即使上述三个条件(SSIZE_MAX、EOF、中断)不适用,在不检查 return 值的情况下对常规文件使用 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 错误(例如需要多次重新读取的坏块)的情况下是可能的。
获得简短阅读的一种方法(除了您问题中提到的情况之外)是在阅读过程中是否出现 I/O 错误。
假设您有一个大小为 1024 的常规文件,占用两个 512 字节的扇区。你不知道的是,第二扇区坏了,无法读取。打开文件并执行 read(fd, buf, 1024)
将 return 512 而不会设置 errno
。如果您再次尝试读取 ,您会得到 return 值 -1
和 errno = EIO
.
我能够使用设备映射器的 error
功能在 Linux 上对此进行测试。
由于您的程序无法执行任何操作来排除 I/O 错误的可能性,这意味着假设 [=15] 中的任何正 return 值都是不安全的=] 必须表示您读取了请求的字节数。