C++providesthefollowingclassestoperformoutputandinputofcharactersto/fromfiles:
ofstream:Streamclasstowriteonfiles
ifstream:Streamclasstoreadfromfiles
fstream:Streamclasstobothreadandwritefrom/tofiles.Theseclassesarederiveddirectlyorindirectlyfromtheclassesistream,andostream.Wehavealreadyusedobjectswhosetypesweretheseclasses:cinisanobjectofclassistreamandcoutisanobjectofclassostream.Therefore,wehavealreadybeenusingclassesthatarerelatedtoourfilestreams.Andinfact,wecanuseourfilestreamsthesamewaywearealreadyusedtousecinandcout,withtheonlydifferencethatwehavetoassociatethesestreamswithphysicalfiles.Let'sseeanexample:
| //basicfileoperations#include<iostream>#include<fstream>usingnamespacestd;intmain(){ofstreammyfile;myfile.open("example.txt");myfile<<"Writingthistoafile.\n";myfile.close();return0;} | [fileexample.txt]Writingthistoafile. |
Thiscodecreatesafilecalledexample.txtandinsertsasentenceintoitinthesamewayweareusedtodowithcout,butusingthefilestreammyfileinstead.Butlet'sgostepbystep:
Openafile
Thefirstoperationgenerallyperformedonanobjectofoneoftheseclassesistoassociateittoarealfile.Thisprocedureisknownastoopenafile.Anopenfileisrepresentedwithinaprogrambyastreamobject(aninstantiationofoneoftheseclasses,inthepreviousexamplethiswasmyfile)andanyinputoroutputoperationperformedonthisstreamobjectwillbeappliedtothephysicalfileassociatedtoit.Inordertoopenafilewithastreamobjectweuseitsmemberfunctionopen():open(filename,mode);Wherefilenameisanull-terminatedcharactersequenceoftypeconstchar*(thesametypethatstringliteralshave)representingthenameofthefiletobeopened,andmodeisanoptionalparameterwithacombinationofthefollowingflags:
ios::in | Openforinputoperations. |
ios::out | Openforoutputoperations. |
ios::binary | Openinbinarymode. |
ios::ate | Settheinitialpositionattheendofthefile.Ifthisflagisnotsettoanyvalue,theinitialpositionisthebeginningofthefile. |
ios::app | Alloutputoperationsareperformedattheendofthefile,appendingthecontenttothecurrentcontentofthefile.Thisflagcanonlybeusedinstreamsopenforoutput-onlyoperations. |
ios::trunc | Ifthefileopenedforoutputoperationsalreadyexistedbefore,itspreviouscontentisdeletedandreplacedbythenewone. |
AlltheseflagscanbecombinedusingthebitwiseoperatorOR(|).Forexample,ifwewanttoopenthefileexample.bininbinarymodetoadddatawecoulddoitbythefollowingcalltomemberfunctionopen():
12 | ofstreammyfile;myfile.open("example.bin",ios::out|ios::app|ios::binary); |
Eachoneoftheopen()memberfunctionsoftheclassesofstream,ifstreamandfstreamhasadefaultmodethatisusedifthefileisopenedwithoutasecondargument:
class | defaultmodeparameter |
---|
ofstream | ios::out |
ifstream | ios::in |
fstream | ios::in|ios::out |
Forifstreamandofstreamclasses,ios::inandios::outareautomaticallyandrespectivelyassumed,evenifamodethatdoesnotincludethemispassedassecondargumenttotheopen()memberfunction.Thedefaultvalueisonlyappliedifthefunctioniscalledwithoutspecifyinganyvalueforthemodeparameter.Ifthefunctioniscalledwithanyvalueinthatparameterthedefaultmodeisoverridden,notcombined.Filestreamsopenedinbinarymodeperforminputandoutputoperationsindependentlyofanyformatconsiderations.Non-binaryfilesareknownastextfiles,andsometranslationsmayoccurduetoformattingofsomespecialcharacters(likenewlineandcarriagereturncharacters).Sincethefirsttaskthatisperformedonafilestreamobjectisgenerallytoopenafile,thesethreeclassesincludeaconstructorthatautomaticallycallstheopen()memberfunctionandhastheexactsameparametersasthismember.Therefore,wecouldalsohavedeclaredthepreviousmyfileobjectandconductedthesameopeningoperationinourpreviousexamplebywriting:
| ofstreammyfile("example.bin",ios::out|ios::app|ios::binary); |
Combiningobjectconstructionandstreamopeninginasinglestatement.Bothformstoopenafilearevalidandequivalent.Tocheckifafilestreamwassuccessfulopeningafile,youcandoitbycallingtomemberis_open()withnoarguments.Thismemberfunctionreturnsaboolvalueoftrueinthecasethatindeedthestreamobjectisassociatedwithanopenfile,orfalseotherwise:
| if(myfile.is_open()){/*ok,proceedwithoutput*/} |
Closingafile
Whenwearefinishedwithourinputandoutputoperationsonafileweshallcloseitsothatitsresourcesbecomeavailableagain.Inordertodothatwehavetocallthestream'smemberfunctionclose().Thismemberfunctiontakesnoparameters,andwhatitdoesistoflushtheassociatedbuffersandclosethefile:
Oncethismemberfunctioniscalled,thestreamobjectcanbeusedtoopenanotherfile,andthefileisavailableagaintobeopenedbyotherprocesses.Incasethatanobjectisdestructedwhilestillassociatedwithanopenfile,thedestructorautomaticallycallsthememberfunctionclose().
Textfiles
Textfilestreamsarethosewherewedonotincludetheios::binaryflagintheiropeningmode.Thesefilesaredesignedtostoretextandthusallvaluesthatweinputoroutputfrom/tothemcansuffersomeformattingtransformations,whichdonotnecessarilycorrespondtotheirliteralbinaryvalue.Dataoutputoperationsontextfilesareperformedinthesamewayweoperatedwithcout:
| //writingonatextfile#include<iostream>#include<fstream>usingnamespacestd;intmain(){ofstreammyfile("example.txt");if(myfile.is_open()){myfile<<"Thisisaline.\n";myfile<<"Thisisanotherline.\n";myfile.close();}elsecout<<"Unabletoopenfile";return0; | [fileexample.txt]Thisisaline.Thisisanotherline. |
Datainputfromafilecanalsobeperformedinthesamewaythatwedidwithcin:
| //readingatextfile#include<iostream>#include<fstream>#include<string>usingnamespacestd;intmain(){stringline;ifstreammyfile("example.txt");if(myfile.is_open()){while(getline(myfile,line)){cout<<line<<endl;}myfile.close();}elsecout<<"Unabletoopenfile";return0;} | Thisisaline.Thisisanotherline. |
Thislastexamplereadsatextfileandprintsoutitscontentonthescreen.Wehavecreatedawhileloopthatreadsthefilelinebyline,using
getline.Thevaluereturnedbygetlineisareferencetothestreamobjectitself,whichwhenevaluatedasabooleanexpression(asinthiswhile-loop)istrueifthestreamisreadyformoreoperations,andfalseifeithertheendofthefilehasbeenreachedorifsomeothererroroccurred.Checkingstateflags
Inadditiontogood(),whichcheckswhetherthestreamisreadyforinput/outputoperations,othermemberfunctionsexisttocheckforspecificstatesofastream(allofthemreturnaboolvalue):bad()Returnstrueifareadingorwritingoperationfails.Forexampleinthecasethatwetrytowritetoafilethatisnotopenforwritingorifthedevicewherewetrytowritehasnospaceleft.fail()Returnstrueinthesamecasesasbad(),butalsointhecasethataformaterrorhappens,likewhenanalphabeticalcharacterisextractedwhenwearetryingtoreadanintegernumber.eof()Returnstrueifafileopenforreadinghasreachedtheend.good()Itisthemostgenericstateflag:itreturnsfalseinthesamecasesinwhichcallinganyofthepreviousfunctionswouldreturntrue.Inordertoresetthestateflagscheckedbyanyofthesememberfunctionswehavejustseenwecanusethememberfunctionclear(),whichtakesnoparameters.getandputstreampointers
Alli/ostreamsobjectshave,atleast,oneinternalstreampointer:ifstream,likeistream,hasapointerknownasthegetpointerthatpointstotheelementtobereadinthenextinputoperation.ofstream,likeostream,hasapointerknownastheputpointerthatpointstothelocationwherethenextelementhastobewritten.Finally,fstream,inheritsboth,thegetandtheputpointers,fromiostream(whichisitselfderivedfrombothistreamandostream).Theseinternalstreampointersthatpointtothereadingorwritinglocationswithinastreamcanbemanipulatedusingthefollowingmemberfunctions:tellg()andtellp()
Thesetwomemberfunctionshavenoparametersandreturnavalueofthemembertypepos_type,whichisanintegerdatatyperepresentingthecurrentpositionofthegetstreampointer(inthecaseoftellg)ortheputstreampointer(inthecaseoftellp).seekg()andseekp()
Thesefunctionsallowustochangethepositionofthegetandputstreampointers.Bothfunctionsareoverloadedwithtwodifferentprototypes.Thefirstprototypeis:seekg(position);seekp(position);
Usingthisprototypethestreampointerischangedtotheabsolutepositionposition(countingfromthebeginningofthefile).Thetypeforthisparameteristhesameastheonereturnedbyfunctionstellgandtellp:themembertypepos_type,whichisanintegervalue.Theotherprototypeforthesefunctionsis:seekg(offset,direction);seekp(offset,direction);
Usingthisprototype,thepositionofthegetorputpointerissettoanoffsetvaluerelativetosomespecificpointdeterminedbytheparameterdirection.offsetisofthemembertypeoff_type,whichisalsoanintegertype.Anddirectionisoftypeseekdir,whichisanenumeratedtype(enum)thatdeterminesthepointfromwhereoffsetiscountedfrom,andthatcantakeanyofthefollowingvalues:ios::beg | offsetcountedfromthebeginningofthestream |
ios::cur | offsetcountedfromthecurrentpositionofthestreampointer |
ios::end | offsetcountedfromtheendofthestream |
Thefollowingexampleusesthememberfunctionswehavejustseentoobtainthesizeofafile: | //obtainingfilesize#include<iostream>#include<fstream>usingnamespacestd;intmain(){longbegin,end;ifstreammyfile("example.txt");begin=myfile.tellg();myfile.seekg(0,ios::end);end=myfile.tellg();myfile.close();cout<<"sizeis:"<<(end-begin)<<"bytes.\n";return0;} [/code] | sizeis:40bytes. |
Binaryfiles
Inbinaryfiles,toinputandoutputdatawiththeextractionandinsertionoperators(<<and>>)andfunctionslikegetlineisnotefficient,sincewedonotneedtoformatanydata,anddatamaynotusetheseparationcodesusedbytextfilestoseparateelements(likespace,newline,etc...).Filestreamsincludetwomemberfunctionsspecificallydesignedtoinputandoutputbinarydatasequentially:writeandread.Thefirstone(write)isamemberfunctionofostreaminheritedbyofstream.Andreadisamemberfunctionofistreamthatisinheritedbyifstream.Objectsofclassfstreamhavebothmembers.Theirprototypesare:write(memory_block,size);read(memory_block,size);
Wherememory_blockisoftype"pointertochar"(char*),andrepresentstheaddressofanarrayofbyteswherethereaddataelementsarestoredorfromwherethedataelementstobewrittenaretaken.Thesizeparameterisanintegervaluethatspecifiesthenumberofcharacterstobereadorwrittenfrom/tothememoryblock. | //readingacompletebinaryfile#include<iostream>#include<fstream>usingnamespacestd;ifstream::pos_typesize;char*memblock;intmain(){ifstreamfile("example.bin",ios::in|ios::binary|ios::ate);if(file.is_open()){size=file.tellg();memblock=newchar[size];file.seekg(0,ios::beg);file.read(memblock,size);file.close();cout<<"thecompletefilecontentisinmemory";delete[]memblock;}elsecout<<"Unabletoopenfile";return0;} | thecompletefilecontentisinmemory |
Inthisexampletheentirefileisreadandstoredinamemoryblock.Let'sexaminehowthisisdone:First,thefileisopenwiththeios::ateflag,whichmeansthatthegetpointerwillbepositionedattheendofthefile.Thisway,whenwecalltomembertellg(),wewilldirectlyobtainthesizeofthefile.Noticethetypewehaveusedtodeclarevariablesize:ifstream::pos_typeisaspecifictypeusedforbufferandfilepositioningandisthetypereturnedbyfile.tellg().Thistypeisdefinedasanintegertype,thereforewecanconductonitthesameoperationsweconductonanyotherintegervalue,andcansafelybeconvertedtoanotherintegertypelargeenoughtocontainthesizeofthefile.Forafilewithasizeunder2GBwecoulduseint:12 | intsize;size=(int)file.tellg(); |
Oncewehaveobtainedthesizeofthefile,werequesttheallocationofamemoryblocklargeenoughtoholdtheentirefile:Rightafterthat,weproceedtosetthegetpointeratthebeginningofthefile(rememberthatweopenedthefilewiththispointerattheend),thenreadtheentirefile,andfinallycloseit:123 | file.seekg(0,ios::beg);file.read(memblock,size);file.close(); |
Atthispointwecouldoperatewiththedataobtainedfromthefile.Ourprogramsimplyannouncesthatthecontentofthefileisinmemoryandthenterminates.BuffersandSynchronization
Whenweoperatewithfilestreams,theseareassociatedtoaninternalbufferoftypestreambuf.Thisbufferisamemoryblockthatactsasanintermediarybetweenthestreamandthephysicalfile.Forexample,withanofstream,eachtimethememberfunctionput(whichwritesasinglecharacter)iscalled,thecharacterisnotwrittendirectlytothephysicalfilewithwhichthestreamisassociated.Insteadofthat,thecharacterisinsertedinthatstream'sintermediatebuffer.Whenthebufferisflushed,allthedatacontainedinitiswrittentothephysicalmedium(ifitisanoutputstream)orsimplyfreed(ifitisaninputstream).Thisprocessiscalledsynchronizationandtakesplaceunderanyofthefollowingcircumstances:Whenthefileisclosed:beforeclosingafileallbuffersthathavenotyetbeenflushedaresynchronizedandallpendingdataiswrittenorreadtothephysicalmedium.Whenthebufferisfull:Buffershaveacertainsize.Whenthebufferisfullitisautomaticallysynchronized.Explicitly,withmanipulators:Whencertainmanipulatorsareusedonstreams,anexplicitsynchronizationtakesplace.Thesemanipulatorsare:flushandendl.Explicitly,withmemberfunctionsync():Callingstream'smemberfunctionsync(),whichtakesnoparameters,causesanimmediatesynchronization.Thisfunctionreturnsanintvalueequalto-1ifthestreamhasnoassociatedbufferorincaseoffailure.Otherwise(ifthestreambufferwassuccessfullysynchronized)itreturns0.使用seekg,seekp时要小心,如f.seekg(n);当n大于文件大小时会出现莫名其妙错误,正确用法是用tellg或者tellp求出文件大小,如下例:stringstr1="HelloWorld.\n";stringstr2="WelcometoBosch.yumen\n";f.open("liaoStr.txt",fstream::out);f<<str1;f<<str2;f.clear();f.close();f.open("liaoStr.txt",fstream::in);intbegin=0;f.seekg(0,ios_base::end);//定位到文件末尾intlen=f.tellg();//计算文件大小while(!f.eof())//用f.good()更好{intoffset=begin*12;if(offset>len)break;f.seekg(offset,ios_base::beg);f>>str1;cout<<str1<<endl;begin++;}f.close(); |
来源:http://www.cplusplus.com/doc/tutorial/files/参考中文博客:http://www.cppblog.com/saga/archive/2007/06/19/26652.htmlhttp://blog.csdn.net/typecool/article/details/5863247