fopen /open区别
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/write和fread/fwrite区别
1,fread是带缓冲的,read不带缓冲.
2,fopen是标准c里定义的,open是POSIX中定义的.
3,fread可以读一个结构.read在linux/unix中读二进制与普通文件没有区别.
4,fopen不能指定要创建文件的权限.open可以指定权限.
5,fopen返回指针,open返回文件描述符(整数).
6,linux/unix中任何设备都是文件,都可以用open,read.
如果文件的大小是8k。
你如果用read/write,且只分配了2k的缓存,则要将此文件读出需要做4次系统调用来实际从磁盘上读出。
如果你用fread/fwrite,则系统自动分配缓存,则读出此文件只要一次系统调用从磁盘上读出。
也就是用read/write要读4次磁盘,而用fread/fwrite则只要读1次磁盘。效率比read/write要高4倍。
如果程序对内存有限制,则用read/write比较好。
都用fread 和fwrite,它自动分配缓存,速度会很快,比自己来做要简单。如果要处理一些特殊的描述符,用read 和write,如套接口,管道之类的
系统调用write的效率取决于你buf的大小和你要写入的总数量,如果buf太小,你进入内核空间的次数大增,效率就低下。而fwrite会替你做缓存,减少了实际出现的系统调用,所以效率比较高。
如果只调用一次(可能吗?),这俩差不多,严格来说write要快一点点(因为实际上fwrite最后还是用了write做真正的写入文件系统工作),但是这其中的差别无所谓。
看了上面如果不理解双缓冲继续读
有一个我们经常提出的问题就是fread,read的区别。(当然这两个分别代表了操作文件系统的两套不同的函数,包括open,read, write, seek 等)。我们都知道,他们的区别就是一个(read)是UNIX 中的系统调用,是类UNIX系统,提供给程序员操作文件的接口(要不然你如何操作文件?);而另外一个则是C语言提供的读取文件的函数库,自然这个函数库(ANSI)的实现是以对应的系统调用为基础的。
那么为什么C语言的函数库需要向我们提供这样的包装,而其他的系统调用(像进程、线程管理与通信等等)没有这样的包装呢?
这当然是有原因的,也就是我们常说的有缓冲读写和无缓冲读写。
但是,我们进一步学习了UNIX系统中,直接I/O的概念之后,对上面的了解需要更深一步了。
为什么要缓冲?
我们先不管用户态、核心态这些事情,我们先思考,读取外设上的文件为什么需要缓冲。
(我们知道,一般意义上流的概念已经被使用到了文件读写中,这个概念与缓冲的概念没有关系。)
我们使用函数向某个文件从当前流标签所在位置,读取n个字符。我们也会使用函数想文件的某个流位置写如n字符。但是,当这种写的动作小、而频繁。每次写又必须反映到硬盘上,也就是说需要频繁的操作硬盘,写一些小的更改,这是非常耗损效率。所以自然我们想到了,我们设立一个缓冲区,将那些要写如的数据先写到缓冲区中,当缓冲区满,或者其他情况发生的是否,我们在一起将他们写入到硬盘上。这样可以大大提高应用程序读写文件的速度。
这就是为什么需要缓冲,根本原因我认为是磁盘等外设的数据还和内存的速度相差甚远,所以我们不希望由于操作外设的原因让本来很快的内存和CPU跟着一起慢,我们想的办法:一是异步写(但这有时候不能符合应用要求),二就是缓冲读写。
而我们通常所理解的就是,read体系,就是那种无缓冲读写,不管是读还是写,调用这个体系的函数,会马上启动一次外设操作,读取数据或者写入数据。而fread体系则,使用了缓冲读写的方式,一定时间才调用read体系的函数。
上面的认识,事实上可以一定程度上说明问题的。但是,我们也太低估UNIX系统的智商了,要知道,不只是应用程序需要与外设进行交互,操作系统更是要与外设频繁的交互。(事实上应用程序是通过操作系统与外设交互的,所以就有了用户态和核心态概念)。
来源:http://www.cnblogs.com/NeilHappy/archive/2013/03/12/2955552.html
http://www.cnblogs.com/shengge/articles/2033129.html