【问题标题】:What is the difference between read() and fread()?read() 和 fread() 有什么区别?
【发布时间】:2010-10-09 16:58:52
【问题描述】:

我正在阅读linux工具badblocks的源代码。他们在那里使用read() 函数。与标准 C fread() 函数有区别吗? (我没有将论点视为差异。)

【问题讨论】:

    标签: c file file-io


    【解决方案1】:

    read() --> 直接使用这个系统调用内核并执行IO操作。

    fread() --> 是标准库中提供的函数。

    调用fread()主要用于存储struct数据的二进制文件数据。 这两者之间的主要区别在于您的应用程序中的系统调用数量。

    fread() 类型的标准 IO 库函数针对系统调用进行了优化,而不是您的应用程序进行系统调用。

    【讨论】:

      【解决方案2】:

      据我所知,read() 级别的 API 不进行缓冲 - 因此,如果您 read() 一次 1 个字节,与使用 fread() 执行相同操作相比,您将面临巨大的性能损失。 fread() 会在你要求时拉出一个积木并分发出去。 read() 将在每次调用时进入内核。

      【讨论】:

        【解决方案3】:

        家庭read() -> openclosereadwrite
        家人fread() -> fopen, fclose, fread, fwrite

        家庭阅读:

        • 是系统调用
        • 未格式化 IO:我们有未格式化的字节流

        家庭恐惧

        • 是标准 C 库 (libc) 的函数
        • 使用内部缓冲区
        • 对于其中一些是格式化的 IO(带有“%..”参数)
        • 始终使用 Linux 缓冲区缓存

        更多细节here,虽然请注意这篇文章包含一些不正确的信息。

        【讨论】:

        • read 和 fread 列表中的最后两个要点都是无稽之谈。默认情况下,这两个系列都使用缓冲区缓存,而使用哪一个与您访问的是字符设备、块设备还是常规文件无关
        • AIB 混淆了两层缓冲——内核缓冲在两种情况下都会发生(我通常称之为 Linux 缓冲区缓存),但在用户空间中进行缓冲以减少系统调用的总数我认为只有 fread 才会发生。
        • @Marcus 我已经消除了答案中的大部分误解。
        【解决方案4】:

        read() 是低级别的无缓冲读取。它在 UNIX 上进行直接系统调用。

        fread() 是 C 库的一部分,提供缓冲读取。它通常通过调用read() 来填充其缓冲区来实现。

        【讨论】:

        • 那么有3个缓冲区?硬盘有一个,/dev/hda 也有缓冲和fread。这是正确的吗?
        • 是的。您可以使用“fflush”刷新第三个,使用 fsync 刷新第二个。我不知道刷新硬盘缓冲区的方法。
        • fflush() 仅适用于 fwrite(),它与 ​​write() 的关系与 fread() 必须与 read() 具有相同的关系。
        • @Darron 我更像是一个 Linux 人,问题是关于 Linux 的。它可能因操作系统而异,但通常可以假设在 Linux fread 调用中读取。
        【解决方案5】:

        如果您将使用一种的代码转换为使用另一种的代码,您应该注意一个区别:

        • fread 阻塞,直到您请求的字节数被读取,或文件结束,或发生错误。
        • read 也会阻塞,但如果你要求说 4kB,它可能会在读取 1kB 后返回,即使文件还没有结束。

        这可能会导致细微的错误,因为它取决于文件的存储位置、缓存等。

        【讨论】:

          【解决方案6】:

          read 是一个系统调用,而fread 是 C 标准库中的一个函数。

          【讨论】:

          • @Jānis Gruzis,这取决于fread 的实现。主要是因为无法保证系统调用read 可用。 Wikipedia read page
          • @JānisGruzis 我刚刚检查了它在 Windows 上是否相同,令我惊讶的是,我发现 their read is deprecated。大概是他们的fread 调用_read 而不是read?无论如何,似乎不是每个fread 都必须调用read
          猜你喜欢
          • 2012-02-11
          • 2011-02-14
          • 2017-05-13
          • 2016-07-18
          • 1970-01-01
          • 2017-12-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多