zoukankan      html  css  js  c++  java
  • 读文件fread的问题

    fread -从打开的fd中读取数据,并且是有缓存

    man page

           #include <stdio.h>
           size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    

    坑:

    1. fread 不一定返回你想读的长度, 即返回值不一定等于size * nmemb , 即使还没有eof。所以你要判断判断返回值
    2. size 应该等于 1, 什么原因忘了,之前被坑过
    while ((bytes = fread (data, 1, 1024, inFile)) != 0)
        MD5_Update (&mdContext, data, 1024);
    

    这样就完蛋了

    while ((bytes = fread (data, 1, 1024, inFile)) != 0)
        MD5_Update (&mdContext, data, bytes);
    

    至于fread 和 read 的区别

    总所周知的read 是系统调用,没有缓存的,而fread 是glibc提供的方法,以及 fread 会调用 read,但具体区别呢
    以下glibc 的源码

    _IO_size_t
    _IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
    {
      _IO_size_t bytes_requested = size * count;
      _IO_size_t bytes_read;
      CHECK_FILE (fp, 0);
      if (bytes_requested == 0)
        return 0;
      _IO_acquire_lock (fp);
      bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
      _IO_release_lock (fp);
      return bytes_requested == bytes_read ? count : bytes_read / size;
    }
    libc_hidden_def (_IO_fread)
     
    #ifdef weak_alias
    weak_alias (_IO_fread, fread)
     
    # ifndef _IO_MTSAFE_IO
    strong_alias (_IO_fread, __fread_unlocked)
    libc_hidden_def (__fread_unlocked)
    weak_alias (_IO_fread, fread_unlocked)
    # endif
    #endif
    

    使用strace 分析

    void c_read() {
      const uint64_t MAXDATABUFF = 1024;
    
      FILE *f = fopen("dfs.s","rb");
      unsigned char data[MAXDATABUFF] = {0};
      int bytes;
      while ((bytes = fread (data, 1, 1024, f)) != 0){}
      fclose(f);
    }
    
    void os_read() {
      const uint64_t MAXDATABUFF = 1024;
    
      int fd = open("dfs.s",O_RDONLY);
      unsigned char data[MAXDATABUFF] = {0};
      int bytes;
      while ((bytes = read (fd, data, 1024)) != 0){}
      close(fd);
    }
    
    int main(){
        c_read();
    }
    

    对比两种方式编译时 -o0 禁止优化
    read

    brk(0x55ffa6698000)                     = 0x55ffa6698000
    openat(AT_FDCWD, "dfs.s", O_RDONLY)     = 3
    read(3, "mmap(0x7f45e1822000, 307200, PRO"..., 1024) = 1024
    read(3, "0x56272ef19000
    openat(AT_FDCWD, "..., 1024) = 1024
    read(3, "NLY|O_CLOEXEC) = 3
    read(3, "\177"..., 1024) = 1024
    read(3, "329272, ...}) = 0
    mmap(NULL, 133"..., 1024) = 1024
    read(3, "AD|PROT_WRITE, MAP_PRIVATE|MAP_F"..., 1024) = 1024
    read(3, "x7f31e0e78000, 1359872, PROT_REA"..., 1024) = 1024
    read(3, "        = 0
    brk(NULL)           "..., 1024) = 381
    read(3, "", 1024)                       = 0
    close(3)                                = 0
    exit_group(0)                           = ?
    

    fread

    openat(AT_FDCWD, "dfs.s", O_RDONLY)     = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=6525, ...}) = 0
    read(3, "mmap(0x7f45e1822000, 307200, PRO"..., 4096) = 4096
    read(3, "AD|PROT_WRITE, MAP_PRIVATE|MAP_F"..., 4096) = 2429
    read(3, "", 4096)                       = 0
    exit_group(0)                           = ?
    

    对比可见, fread 合并多次调用read

    总结

    fread 需要检查返回值

  • 相关阅读:
    linux取随机数shell版本
    PWD简介与妙用(一个免费、随时可用的Docker实验室)
    MySQL基础教程——mysql脚本编写
    MySQL基础教程——创建数据库并插入数据
    MySQL——数据库和 SQL 概念&&MySQL的安装
    卷积计算
    卷积及其应用
    SG函数入门&&HDU 1848
    ACM博弈论基础
    Aho-Corasick自动机
  • 原文地址:https://www.cnblogs.com/hustcpp/p/12424061.html
Copyright © 2011-2022 走看看