zoukankan      html  css  js  c++  java
  • 面试问题——fread和read的区别

    面试碰到了如题的问题,回来百度了一下,解答如下:

    fread返回的是一个FILE结构指针
    而read返回的是一个int的文件号

    前者fopen/fread的实现是靠调用底层的open/read来实现的.

    fopen/fread
    是C标准的库函数,操作的对象是: file stream

    open/read
    是和操作系统有关的系统调用。操作的对象是: “file descriptor”


    f是ANSI的C标准库。后面的是UNIX下的系统调用。

    带f的带有缓冲,是后面的衍生,
    直接和硬件打交道,必须是后面的!

     

    UNIX环境下的C 对二进制流文件的读写有两套班子:1) fopen,fread,fwrite ; 2) open, read, write
    这里简单的介绍一下他们的区别。

    1. fopen
    系列是标准的C库函数;open系列是 POSIX 定义的,是UNIX系统里的system call
    也就是说,fopen系列更具有可移植性;而open系列只能用在 POSIX 的操作系统上
    2.
    使用fopen 系列函数时要定义一个指代文件的对象,被称为文件句柄file handler),是一个结构体;而open系列使用的是一个被称为文件描述符 file descriptor)的int型整数。
    3. fopen
    系列是级别较高的I/O,读写时使用缓冲;而open系列相对低层,更接近操作系统,读写时没有缓冲。由于能更多地与操作系统打交道,open系列可以访问更改一些fopen系列无法访问的信息,如查看文件的读写权限。这些额外的功能通常因系统而异。
    4.
    使用fopen系列函数需要"#include <sdtio.h>";使用open系列函数需要"#include <fcntl.h>" ,链接时要之用libc-lc
    小结:
    总的来说,为了使程序获得更好的可移植性,未到非得使用一些fopen系列无法实现的功能的情况下,fopen系列是首选。

     

    read/writefread/fwrite区别

    1,fread是带缓冲的,read不带缓冲.

    eg:

    如果文件的大小是8k。你如果用read/write,且只分配了2k的缓存,则要将此文件读出需要做4次系统调用来实际从磁盘上读出。
    如果你用fread/fwrite,则系统自动分配缓存,则读出此文件只要一次系统调用从磁盘上读出。
    也就是用read/write要读4次磁盘,而用fread/fwrite则只要读1次磁盘。效率比read/write要高4倍。


    如果程序对内存有限制,则用read/write比较好
    2,fopen
    是标准c里定义的,openPOSIX中定义的
    .
    3,fread
    可以读一个结构. readlinux/unix中读二进制与普通文件没有区别
    .
    4,fopen
    不能指定要创建文件的权限.open可以指定权限
    .
    5,fopen
    返回指针,open返回文件描述符(整数
    ).
    6,linux/unix
    中任何设备都是文件,都可以用
    open,read.

    都用fread fwrite,它自动分配缓存,速度会很快,比自己来做要简单。如果要处理一些特殊的描述符,read write,如套接口,管道之类的
    系统调用write的效率取决于你buf的大小和你要写入的总数量,如果buf太小,你进入内核空间的次数大增,效率就低下。而fwrite会替你做缓存,减少了实际出现的系统调用,所以效率比较高。
    如果只调用一次(可能吗?),这俩差不多,严格来说write要快一点点(因为实际上fwrite最后还是用了write做真正的写入文件系统工作),但是这其中的差别无所谓。

    ——————————————————

     

    表头文件

    #include<stdio.h>

    定义函数

    FILE * fopen(const char * path,const char * mode);

    函数说明

    参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
    mode有下列几种形态字符串:
    r 打开只读文件,该文件必须存在。
    r+ 打开可读写的文件,该文件必须存在。
    w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
    a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
    上 述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。

    返回值

    文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并把错误代码存在errno 中。

    附加说明

    一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

    表头文件

    #include<stdio.h>

    定义函数

    int fclose(FILE * stream);

    函数说明

    fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。

    返回值

    若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。

    错误代码

    EBADF表示参数stream非已打开的文件。

    fread(从文件流读取数据)

    相关函数

    fopen,fwrite,fseek,fscanf

    表头文件

    #include<stdio.h>

    定义函数

    size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);

    函数说明

    fread() 用来从文件流中读取数据。参数stream为已打开的文件指针,参数ptr 指向欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。Fread()会返回实际读取到的nmemb数目,如果此值比参数 nmemb 来得小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生什么情况。

    返回值

    返回实际读取到的nmemb数目。

    fwrite(将数据写至文件流)

    相关函数

    fopen,fread,fseek,fscanf

    表头文件

    #include<stdio.h>

    定义函数

    size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);

    函数说明

    fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。

    返回值

    返回实际写入的nmemb数目。

  • 相关阅读:
    CF698C LRU
    关于 Exists 的几种嵌套查询
    React中使用useState()导致的问题记录
    react报错:Legacy context API has been detected within a strict-mode tree.
    vue-cli3.0 + typescript 构建项目
    VUE3.0 + TS 项目实战 (2)基本写法
    vue图片剪辑
    实现直播间消息评论滚动,顶部消失效果
    js 实现数组元素交换位置
    JS树结构操作:查找、遍历、筛选、树结构和列表结构相互转换,删除对应数据
  • 原文地址:https://www.cnblogs.com/liuliunumberone/p/2038628.html
Copyright © 2011-2022 走看看