fwritewritefreadreadfopenopen函数的区别及效率doc.docx
《fwritewritefreadreadfopenopen函数的区别及效率doc.docx》由会员分享,可在线阅读,更多相关《fwritewritefreadreadfopenopen函数的区别及效率doc.docx(13页珍藏版)》请在冰豆网上搜索。
fwritewritefreadreadfopenopen函数的区别及效率doc
fwrite/write,fread/read,fopen/open函数的区别及效率?
X.比较
1)fwirte/fread:
是带缓冲的,
vvrite/read:
是不带缓冲的
2)fopen是标准c里定义的,不能指定要创建文件的权限,fopen返回指针。
open是POSIX中定义的,可以指定权限,返回文件描述符(整数)。
2.实例说明:
如果文件的大小是8k0
你如果用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做真正的写入文件系统工作),但是这其中的差别无所谓。
2.fwrite和fread的源代码参考源码:
(Microsoft的源代码,在
vc\crt\src\fwrite.c里)
/■【■■【■■【■■【■■【■■【■■【■■【■■【*■【■■【■■【■■【■■【■■【■■【■■【■7"7"7"斗"7"斗"斗"斗"斗"斗"7"斗"
/*、、*'、*'、*'、*'、*'、*'、*A、*A、*'、*'、*'、*'、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*A、*'、*A、*A、*A、*A、*A、*A、*'、*A、*A、*A、*A、*'、*A、*A、*A、*A、*'、*A、*A、*A、*A、*A、*A、*A、S、彳・彳、彳、叫彳、彳彳、叫、彳・彳・
%、%、%、%、%、%、
*fwrite.c-readfromastream
*Copyright(c)1989-1997,MicrosoftCorporation.Allrightsreserved.
*
^Purpose:
*Writetothespecifiedstreamfromtheuser'sbuffer.
*********************************************************************
#include
#include
#include
#include
#include
#include
#include
*size_tfwrite(void^buffer,size_tsize,size_tcount,FILE*stream)-
*writetothespecifiedstreamfromthespecifiedbuffer.
*
^Purpose:
*Writercountfitemsofsize'size'tothespecifiedstreamfrom
*thespecifiedbuffer.Returnwhen'count'itemshavebeenwritten
*ornomoreitemscanbewrittentothestream.
*
*Entry:
*
buffer
-pointertouser'sbuffer
*
size
-sizeoftheitemtowrite
*
count
-numberofitemstowrite
*
stream
-streamtowriteto
*Exit:
Returnsthenumberof(whole)itemsthatwerewrittentothestream.Thismaybelessthan'count'ifanerrororeofoccurred.Inthiscase,ferror()orfeof()shouldbeusedtodistinguishbetweenthetwoconditions.
*Notes:
*
fwritewillattempttobufferthestream(sideeffectofthe_flsbuf
*
*
*
*
*
*
call)ifnecessary.
NomorethanOxFFFEbytesmaybewrittenoutatatimebyacalltowrite().Further,write()doesnothandlehugebuffers.Therefore,inlargedatamodels,thewriterequestisbrokendownintochunksthatdonotviolatetheseconsiderations-Eachofthesechunksis
*
*
*
*
*
processedmuchlikeanfwrite()callinasmalldatamodel(byacallto_nfwrite()).
Thiscodedependson_iob[]beinganeararray.
*
*
*
*
MTHREAD/DLL-Handledinjusttwolayerssinceitissmalldatamodel.Theouterlayer,fwrite(),handlesstreamlocking/unlockingandcalls_fwrite_lk()todothework._fwrite_lk()isthesameasthesingle-thread,smalldatamodelversionoffwrite().
*********************************************************************
KJ"KJ"/
/
#ifdef_MT
/*definelocking/unlockingversion*/size_t_cdeclfwrite(
constvoid*buffer,
size_tsize,
size_tcount,FILE*stream
)
{
size_tretval;
_lock_str(stream);/*lockstream*/
retval=_fwrite_lk(buffer5size,count,stream);/*dotheread*/_unlock_str(stream);/*unlockstream*/
returnretval;
}
#end讦/*MT*/
/*definethenormalversion*/#ifdef_MT
size_t_cdecl_fwrite」k(
#else/*_MT*/
size_t_cdeclfwrite(
#endif/*_MT*/
[
constvoid*buffer,size_tsize,size_tnum,
FILE*stream)
\
constchar*data;unsignedtotal;unsignedcount;unsignedbufsize;unsignednbytes;unsignednwritten;
intc;
/*pointtowheredatacomesfromnext*/
/*totalbytestowrite*/
/*numbyteslefttowrite*/
/*sizeofstreambuffer*/
/*numberofbytestowritenow*/
/*numberofbyteswritten*/
/*atempchar*/
/*initializelocalvars*/
data=buffer;
count=total=size*num;
if(0==count)return0;
if(anybuf(stream))
/*alreadyhasbuffer,useitssize*/bufsize=stream->_bufsiz;
else
#ifdefined(_M_M68K)||defined(_M_MPPC)/*assumewillgetBUFSIZbuffer*/bufsize=BUFSIZ;
#else/*defined(_M_M68K)||defined(_M_MPPC)*//*assumewillget_INTERNAL_BUFSIZbuffer*/bufsize=」NTERNAL_BUFSIZ;
#endif产defined(_M_M68K)||defined(_M_MPPC)*/
/*hereisthemainloop~wegothroughhereuntilwe'redone*/while(count!
=0)
{
/*如果缓冲区还有空间,拷贝数据到缓冲区。
ifthebufferisbigandhasroom,copydatatobuffer*/
if(bigbuf(stream)&&stream->_cnt!
=0)
{
/*howmuchdowewant?
*/
nbytes=(count<(unsigned)stream->_cnt)?
count:
stream->_cnt;memcpy(stream->_ptr,data,nbytes);
/*updatestreamandamtofdatawritten*/
count-=nbytes;stream->_cnt-=nbytes;stream->_ptr+=nbytes;data+=nbytes;
}
elseif(count>=bufsize)
{
/*如果发送数据量大于默认缓冲区的大小,写数据时调用“write”函数来写“默认缓冲区大小”整数倍的字节数,
Ifwehavemorethanbufsizecharstowrite,writedatabycallingwritewithanintegralnumberofbufsizblocks.Ifwereachhereandwehaveabigbuffer,itmustbefullso_flushit.*/
if(bigbuf(stream))
{
if(_flush(stream))
{
/*eiTor,streamflagsset—weTeoutofhere*/return(total・count)/size;
}
}
/*calccharstoread一(count/bufsize)*bufsize*/nbytes=(bufsize?
(count・count%bufsize):
counl);
nwritten=_write(_fileno(stream),data,nbytes);
if(nwritten==(unsigned)EOF)
{
/*eiToroutofhere*/stream->Hag|=_IOERR;return(total-count)/size;
}
/*updatecountanddatatoreflectwrite*/
count-=nwritten;
data+=nwritten;
if(nwritten{
/*error―outofhere*/stream->_flag|=_IOERR;return(total・count)/size;
}
}
else
{
/*缓冲区满并且没有足够的字符来直接写,则用_flsbuf*/
/*bufferfullandnotenoughcharstododirectwrite,sodoa_flsbuf.*/c=*data;/*_flsbufwriteonechar,thisisit*/if(_flsbuf(c,stream)==EOF)
{
/*eirororeof,streamflagssetby_flsbuf*/return(total・count)/size;
}
/*_flsbufwroteachar~updatecount*/
++data;
・-count;
/*updatebuffersize*/bufsize=stream->_bufsiz>0?
stream->_bufsiz:
1;
}
}
/*wefinishedsuccessfully,sojustreturnnum*/
returnnum;
}
/
f•丫•♦丫•rJ*rj*rj*♦丫•♦丫••丫•rj*•丫••丫••丫••丫••丫•♦丫••丫•rJ*•丫•♦卜•丫••丫•♦丫••丫••丫•♦丫••丫•♦丫•
***********
^fread.c-readfromastream
*
Copyright(c)1989-1997,MicrosoftCorporation•Allrightsreserved.
*Purpose:
Readfromthespecifiedstreamintotheuser'sbuffer.
♦.、•.、♦.、•.、•.、•.、f♦.、•.、♦.、•.、♦.、•.、♦.、•.、•.、•.、♦.、♦.、•.、♦.、♦.、•.、•.、•.、♦.、•.、•.、♦.、♦.、♦.、•.、•.、•.、♦.、♦.、•.、•.、♦.、•.、•.、•.、•.、♦.、•.、•.、♦.、♦.、♦.、•.、♦.、♦.、•.、•.、•.、•.、•.、•.、•.、♦.、♦.、•.、•.、•.、♦.、•.、•.、•.、•.、
#include
#include
#include
#include
#include
#include
/***
*size_tfread(void*buffer,size_tsize,size_tcount,FILE*stream)-
*readfromspecifiedstreamintothespecifiedbuffer.
*
*Purpose:
*Entry:
*
buffersizecountstream
Read'counfitemsofsize'size'fromthespecifiedstreamintothespecifiedbuffer.Returnwhen'count'itemshavebeenreadinornomoreitemscanbereadfromthestream.
・pointertouser'sbuffer
・sizeoftheitemtoreadin
-numberofitemstoread
-streamtoreadfrom*Exit:
Returnsthenumberof(whole)itemsthatwerereadintothebuffer.Thismaybelessthan^ount1ifanerrororeofoccurred.Inthiscase,ferror()orfeof()shouldbeusedtodistinguishbetweenthetwoconditions.
*Notes:
freadwillattempttobufferthestream(sideeffectofthe_filbufcall)ifnecessary.
NomorethanOxFFFEbytesmaybereadinatatimebyacalltoread().Further,read()doesnothandlehugebuffers.Therefore,inlargedatamodels,thereadrequestisbrokendownintochunksthatdonotviolatetheseconsiderations.Eachofthesechunksisprocessedmuchlikeanfread()callinasmalldatamodel(byacallto_nfread()).
MTHREAD/DLL-Handledinthreelayers.fread()handlesthelocking
means*mu
6iunuj_0zis
'OZISOzis
“gjjnq*piOA
/*丄凶一*/J!
PU。
#)pBQJJ|99p0—)_0ZIS
/*1W_*/os*#)”[—ppgjj—joopo—J-0ZIS1WFPJ!
#
/*UOISJOAIUUIJOU。
屮9UIJ9p*/
/*UAT*/J!
PU0#{
:
[FAQIUJDJ9J
/*UJU0J1S>po[un*/t(uiuoj)s)J)s_>]ooiun_
/*puojop*/t(iuu0j)s4iunoo4ozis冇0Jjnq)”[—ppay—二[eaioj
/*UIV0JJS>po[*/:
(iuEa【)s)HS—
MaQ1_9ZIS
}(
UIEOHS*31H
4iunoo厂ozp
6OZIS}_9ZIS
••
Mjjnq*P!
OA
)pUOJJ|30po—J-0ZIS
/*UOISJ0ASui^30|un/§ui>100|ouijop*/1WFPJ!
#
/
/吩・rj*吟・rj・rj・rjwrjwrjwrJw
•、■、・、•、・、•.・•.・•.・•.・•.・■.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・•.・■.・•.・•.・•.・■.・•.・•.・•.・■.・•.・•.・•.・•.・■.・■.・•.・•.・•.・•.・•.・■.、・.、
•()pE9JJJOUOISJOApP0jq)-9I§UTS。
屮SEOUJES0屮SI()”「pPOJJ—•”JOM{PnjOP。
屮Op01()”[—pEOJJ—S(IP9pUESui^oojUJP9J1S。
屮joojposo”E「()pEay\ioA引jojuooq丄•ppouiuwp[[ECUSsiu90UISsjqAei0M2屮isnfUIpoipu^H・nna/avaHHlW/98£
•”jom(unjoB。
屮opoiOpuojju-s[[eopuns”untpoiqpsoSipojui;sonbojpEOj。
屮dnsyjpojq开・()pE9目jouoisjoa[opouinjnpoSjuj“pF®屮V]分iqs。
屮suouius。
屮si()”厂pea厂・”ioa\。
屮opo)()”「pea厂s【[eopuu(pojinbsjji)§uuoiS0j/§uipuo|/§uiAUSsapum
char*data;unsignedtotal;unsignedcount;unsignedbufsize;unsignednbytes;unsignednread;intc;
/*pointtowhereshouldbereadnext*/
/*totalbytestoread*/
/*numbyteslefttoread*/
/*sizeofstreambuffer*/
/*howmuchtoreadnow*/
/*howmuchwedidread*/
/*atempchar*/
/*initializelocalvars*/data=buffer;
if((count=total=size*num)==0)return0;
if(anybuf(stream))
/*alreadyhasbuffer,useitssize*/bufsize=strea>_bufsiz;
else
#ifdefined(_M_M68K)||defined(_M_MPPC)
/*assumewillgetBUFSIZbuffer*/
bufsize=BUFSIZ;
#else/*defined(_M_M68K)||defined(_M_MPPC)*//*assumewillget_INTERNAL_BUFSIZ