c - 从常规文件 : block or return less data? 读取

标签 c io posix

read可以吗?到

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

  • 从常规文件中读取时,不包括:
  • 请求比 SSIZE_MAX 更多的数据
  • 超出 EOF 的阅读
  • 信号中断
  • read(3)建议在从常规文件中读取时,排除上述条件 read永远不会返回比请求更少的字节。

    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提出一个假设,其中 read如果内核希望优先处理其他 I/O,则返回的字节数可能少于请求的字节数。虽然是假设性的,但关键是在任何情况下都无法读取预期返回的数据与请求的完全一样。因此,即使上述三个条件(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 错误(例如需要多次重新读取的坏块)时,这是可能的。

    最佳答案

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

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

    我能够在 Linux 上使用设备映射器的 error 对此进行测试。功能。

    由于您的程序无法排除 I/O 错误的可能性,这意味着假设来自 read 的任何正返回值永远是不安全的。必须意味着您按要求读取了尽可能多的字节。

    关于c - 从常规文件 : block or return less data? 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37042287/

    相关文章:

    c - 将文本文件逐行读入c中的结构

    python - python 2中如何抑制回车?

    io - 值不一致错误: I/O operation on closed file

    c - 为什么 `aio_write` 不允许并发缓冲区访问?

    regex - 如何在符合 POSIX BRE/ERE 的情况下更改我的表达式以返回相同的结果?

    C - 线程同步

    c - C 与汇编程序的效率

    C 多行宏 : do/while(0) vs scope block

    c - 应该始终使用 memcpy 吗?

    c# - 如何访问 SerialPort.Flush() 和 SerialPort.Finalize() 函数