【问题标题】:understand read() in Linux理解 Linux 中的 read()
【发布时间】:2014-05-30 11:09:44
【问题描述】:

我正在查看 read(int fd, void *buf, size_t count) 的手册页

http://man7.org/linux/man-pages/man2/read.2.html

我需要对“在支持查找的文件上,读取操作从当前文件偏移量开始,文件偏移量增加读取的字节数。”这句话进行更多解释。

1) 如果我不想从头开始读取文件,比如在偏移量 100(字节)处读取 1 个字节,是偏移量 100 添加到 fd,即 read(fd+100, buf, 1) ?如果不是,如何在代码中指定偏移量?

2) 我如何知道“文件是否支持搜索”?我通过 spi 总线将 FPGA 作为 spi 设备“打开”,以获取 fd。我正在使用 read() 来读取 FPGA 的寄存器。请问这种情况下是文件支持吗?

谢谢!

【问题讨论】:

    标签: linux file posix system-calls


    【解决方案1】:

    或者,您可能对pread 感兴趣,具体取决于您在做什么。 pread 相当于以原子方式 (1) 保存当前偏移量,(2) 读取您要读取的偏移量,以及 (3) 恢复原始偏移量。

    在第二个问题上,您会知道它是否不是可搜索设备,因为您对 lseek 的调用将失败。我不知道有什么可靠的方法可以提前知道。

    【讨论】:

      【解决方案2】:

      你使用lseek 来移动文件中的位置——所以你会做类似的事情

      lseek(fd, 100, SEEK_SET);
      read(fd, buffer, 1);
      

      读取位置 100 的一个字节。

      但是,虽然这是一个有效的示例,但我建议不要以这种方式读取文件中的单个字节,因为它非常缓慢/昂贵。

      如果你想让随机 io 大规模获取文件中的单个字节,你最好使用mmap 而不是lseek/read

      【讨论】:

        【解决方案3】:

        您需要首先通过 readseek 调用将文件指针(当前文件偏移量)移动到 100。

        【讨论】:

        • 你说的“文件指针”和文件描述符fd一样吗?你的意思是我先读(fd, buf, 100)再读(fd, buf, 1)?谢谢!
        • 不,文件指针是打开文件中的内部定位符。它在 open 时的初始位置通常为 0。在打开文件后尝试使用 seek 调用(或 fseek,如果使用文件指针而不是文件描述符)。这样,您实际上不必花费周期将前 100 个字节移动到缓冲区,而只需将文件中的指针移动到所需的位置。
        • 可以读取 100 个字节来移动文件指针,然后读取 1,但如果“文件”以某种方式支持随机访问,则查找更简洁。
        • 谢谢。原来我的文件不支持搜索。使用 pread 时返回错误 29 (Illegal seek)。那么在这种情况下,我是否必须 read() 100 个字节来移动偏移量,然后 read() 1 个字节?这是唯一的方法吗?
        • 如果这个伪设备真的只支持顺序操作,而不支持随机访问搜索,听起来这是唯一的方法。至少,看看这种方式是否有效。您确定您实际上并没有寻求结束(过去的“EOF”)?您确定您甚至已正确打开文件/伪设备以供读取(并且权限允许读取)?别忘了检查这些东西。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多