Tải bản đầy đủ - 0 (trang)
Chapter 17. Out to the Disk

Chapter 17. Out to the Disk

Tải bản đầy đủ - 0trang

Chapter17.OuttotheDisk

Thischapterdealswithdatastoredondiskratherthanin

memory.Therearetwomainreasonsforusingdiskstorage.

First,informationondiskpersistsevenwhentheelectricity

goesoutorthecomputerisrebooted.Second,some

applicationsinvolvesomuchdatathatitdoesnotfitinmemory.

Forexample,asearchenginethatexamines10billionweb

sites,averaging10kilobyteseach,wouldhavetohandle100

terabytesofdata!

Section17.1dealswiththebasicsofinteractingwithfilesin

Java.Theremainingsectionsaddressspecialdatastructures

andalgorithmsusedwithdatastoredondisk.Twoalgorithms

forcompressingdata,sothatittakesuplessspaceondisk,are

describedinSection17.2.InSection17.3,welookatan

algorithmforsortingdatawhichdoesnotfitinmemory.Finally,

inSection17.4,wediscussB-trees,abinarysearchtreevariant

especiallysuitedfordatastoredondisk.



[Page467(continued)]



17.1.InteractingwithFiles

Thebuilt-injava.iopackagecontainsdozensofclassesfor

readingandwritingdatainmemory,ondisk,andover

networks.Theserelativelysimplecomponentscanbestrung

togetherinahugevarietyofways.Theintentofthisdesignis

togiveexperiencedprogrammersagooddealofcontrolover

inputandoutput.Unfortunately,thevastcollectionofclassesis

confusingandintimidatingtothenewprogrammer.Inthis

section,wewillconcentrateonafewparticularlyusefulclasses,

demonstratinghowtoreadandwritetextanddata.



[Page468]



TextFiles

Webeginwiththesimpletaskofwritingtexttoafile.Wecan

dothisusingthejava.io.PrintWriterclass(Figure17-1).



Figure17-1.Thisprogramalmostworks.



1importjava.io.*;

2

3/**Classtodemonstratetextfileoutput.*/

4publicclassOzymandias{

5

6/**Printastringtoafile.*/

7publicstaticvoidmain(String[]args)throwsIOException{

8PrintWriterout=newPrintWriter("ozymandias.txt");

9out.println("Lookonmyworks,yemighty,anddespair!");

10}

11

12}



ThePrintWriterclasshasaconstructorwhichacceptsafile

nameasaString.Invokingthisconstructormightthrowan

IOException(specifically,aFileNotFoundException)ifthefilein

questiondoesnotexistandcannotbecreated.There'snothing

ourprogramcandoifsuchanexceptionoccurs,sowepassit

onbydeclaringthatmain()mightthrowanIOException.

OncewehaveaPrintWriter,wecaninvokethemethodsprint()

andprintln(),whichworkjustliketheonesprovidedby

System.out.

Whenwerunthisprogram,italmostworks.Itcreatesafile

calledozymandias.txtinthecurrentdirectory(thedirectoryfrom

whichwerantheprogram).Ifweexaminethefile,however,we

discoverthatitisempty!Whathappened?

TheproblemisthatthePrintWriterisbuffered.Inotherwords,

itdoesn'twritetothefileeverytimeweinvokeprintln().

Instead,itsavesupitsoutputuntilithasalargeamount,then

writesallofittothedisk.Thisisareasonablethingtodo,

becauseaccessingthediskisanextremelytime-consuming

operation.Becauseadiskinvolvesphysicalmovingparts,adisk

accesscantakeroughlyamilliontimesaslongasamemory

access.Ontheotherhand,oncethedisk'sread/writeheadisin

therightplace,readingorwritingmoredataatthesameplace

ispracticallyfree.Thus,itismoreefficienttomakeafewlarge

diskaccessesthanmanysmallones.

Inordertogetourprogramtoworkproperly,wemustflush

thebufferthatis,tellthePrintWriter,"Youcanreallysendthat

stufftothedisknow."Wecoulddothisbyinvokingtheflush()

method,butsincewe'redonewiththefile,wemightaswell

closethefilecompletely(Figure17-2).



[Page469]



Figure17-2.ClosingthePrintWriterflushesthe

buffer.



1/**Printastringtoafile.*/

2publicstaticvoidmain(String[]args)throwsIOException{

3PrintWriterout=newPrintWriter("ozymandias.txt");

4out.println("Lookonmyworks,yemighty,anddespair!");

5out.close();

6}



Amoreelaboratewaytowritethisprogramwouldbeto

explicitlycreateaninstanceoftheFileclass,thenattacha

PrintWritertothatfile(Figure17-3).TheFileobjecthandles

interactionwiththedisk,whilethePrintWriterobjectprovides

theprint()andprintln()methods.



Figure17-3.ExplicitlycreatingaFileobject.



1/**Printastringtoafile.*/

2publicstaticvoidmain(String[]args)throwsIOException{

3Filefile=newFile("ozymandias.txt");

4PrintWriterout=newPrintWriter(file);

5out.println("Lookonmyworks,yemighty,anddespair!");

6out.close();

7}



Thereisnoparticularreasontousethismorecomplicated

versionhere,becausePrintWriterhasaconstructorthatletsus

specifythefilenamedirectly.Thisexampledoesdemonstrate

thephilosophyofthejava.iopackage:providemanysimple

componentswhichcanbecombinedtoproducethedesired

behavior.Later,we'llattachadifferent"filter"toaFiletowrite

somethingotherthantext.



Beforemovingon,let'slookatsomeoftheclassesinvolvedin

whatwe'vedonesofar(Figure17-4).



Figure17-4.Classesinvolvedinwritingtexttoa

file.Theshadedclasseshavenotbeendiscussed

previously.

(Thisitemisdisplayedonpage470intheprintversion)



APrintWriterbothisaWriterandcontainsone.Specifically,

whenwehookoneuptoaFile,itcontainsaFileWriter(Figure

17-5).Fortunately,wedon'thavetokeeptrackofallofthese

intermediateobjects;theconstructorsinPrintWriterdothe

workforus.



Figure17-5.APrintWritercancontaina

FileWriter,whichinturncontainsaFile.Each

objectinthischainofferssomeadditional

functionality.

(Thisitemisdisplayedonpage470intheprintversion)



TheobjectSystem.out,incidentally,isaninstanceoftheclass

PrintStream.

Wewouldalsoliketoreadtextinfromfiles.Oddlyenough,

thereisnosuchthingasaPrint-Reader.Instead,wecanuse

thejava.util.Scannerclass.Aswehaveseen,thisclasshas

severalconstructors.OneconstructortakesanInputStream,

suchasSystem.in.Another,usedinthePickUpSticksprogram

inFigure15-29,takesaString.YetanothertakesaFile.



[Page470]

Asanexample,let'swriteaprogramthatreadsaJavaprogram

andprintsthelinescontainingthesubstring"public"(Figure176).



Figure17-6.Thisprogramprintsalllinesofafile

containingthesubstring"public".



1importjava.io.*;

2importjava.util.Scanner;

3

4/**Printalllinescontainingthesubstring"public".*/

5publicclassPrintPublicMembers{

6

7/**Runonthefilespecifiedasargs[0].*/

8publicstaticvoidmain(String[]args)throwsIOException{

9Filefile=newFile(args[0]);

10Scannerin=newScanner(file);



[Page471]

11while(in.hasNextLine()){

12Stringline=in.nextLine();

13if(line.contains("public")){



14System.out.println(line);

15}

16}

17}

18

19}



Runningthisprogramallowsustoseeallofthepublicmethods

ofaclass.Forexample,ifwerunourprogramwiththe

command

javaPrintPublicMembersArrayList.java



weget:

publicclassArrayListimplementsList{

publicArrayList(){

publicvoidadd(Etarget){

publicbooleancontains(Etarget){

publicbooleanisEmpty(){

publicjava.util.Iteratoriterator(){

publicEget(intindex){

publicEremove(intindex){

publicbooleanremove(Etarget){

publicvoidset(intindex,Etarget){

publicintsize(){

publicStringtoString(){



Incidentally,thisprogramtouchesononeofthedeepestideas

incomputerscience:itispossibletowriteprogramsthattreat

otherprogramsasdata.Wehavebeendealingwithonesuch

programthroughoutthisbook:theJavacompiler.Itreadsa

program(asJavasourcecode)fromafileandwritesanother



program(ascompiledJavabytecode)toanotherfile.

Aswithtextoutput,there'smoregoingonbehindthescenes

thanisapparentinthecodewe'vewritten(Figure17-7).



Figure17-7.Classesandinterfacesinvolvedin

readingtextfromafile.Theshadedclasseshave

notbeendiscussedpreviously.

(Thisitemisdisplayedonpage472intheprintversion)



AScannerisassociatedwithaninstanceofsomeclass

implementingtheReadableinterface.Differentthingshappen,

dependingonwhichScannerconstructorweuse:

IftheargumentisaString,theScannercontainsa



StringReader,whichinturncontainstheString.

IftheargumentisaFile,theScannercontainsaFileReader,

whichinturncontainsthatFile.

IftheargumentisaBufferedInputStream(suchas

System.in),theScannercontainsanInputStreamReader,

whichinturncontainsthatBufferedInputStream.



[Page472]

Onceagain,wearethankfulthatwedon'thavetokeeptrackof

allofthis!



DataFiles

Informationinfilesneednotbestoredintext.Ifitisnot

necessaryforhumanstoreadfilesdirectly,textissomewhat

inefficient.Forexample,supposewewanttostorenine-digit

SocialSecuritynumbers.Astext,eachdigitisacharacter,

occupyingonebyteintheASCIIencoding.(Javaactuallyuses

themorecomprehensiveUnicodeencoding.ThewayUnicode

charactersarerepresentedondiskiscomplicated;weignore

thesedetails.)Anine-digitnumbercanalsobestoredinafourbyteint,usinglessthanhalfthespace.Ifhundredsof

thousandsofsuchnumbersarebeingstored,thiscanbea

significantsavings.

Tointeractwithdatastoredinthisbinaryformat,weusethe

classesObjectInputStreamandObjectOutputStream.Theseare

subclassesofInputStreamandOutputStream,respectively

(Figure17-8).



Figure17-8.Classesinvolvedinreadingfromand



writingtoabinarydatafile.

(Thisitemisdisplayedonpage473intheprintversion)



Asasimpleexample,theprograminFigure17-9takesan

optionalcommand-lineargument.Ifanargumentisprovided,it

isstoredinafile(lines1316).Otherwise,thefirstintinthefile

isreadandprintedtothescreen(lines1820).



Figure17-9.Readingandwritingdatainbinary

format.

(Thisitemisdisplayedonpage473intheprintversion)



1importjava.io.*;

2

3/**Exampleofstoringdatainbinaryformat.*/

4publicclassDataFileExample{

5

6/**

7*Ifanintisprovidedonthecommandline,storeitin

8*number.data.Otherwise,readanintfromnumber.data

9*andprintit.

10*/

11publicstaticvoidmain(String[]args)throwsIOException{

12Filefile=newFile("number.data");

13if(args.length>0){

14ObjectOutputStreamout

15=newObjectOutputStream(newFileOutputStream(file));

16out.writeInt(Integer.parseInt(args[0]));



17out.close();

18}else{

19ObjectInputStreamin

20=newObjectInputStream(newFileInputStream(file));

21System.out.println(in.readInt());

22}

23}

24

25}



InadditiontoreadInt()andwriteInt(),therearecorresponding

methodsforalloftheotherprimitivetypes.



[Page473]

TherearealsomethodsreadObject()andwriteObject().Whenwe

writeanobjecttoanObjectOutputStream,Javaautomatically

writesthecontentsoftheobject'sfields.Ifthesearereferences

tootherobjects,thoseobjectsarewrittenaswell.The

observantreader,recallingChapter16,willseeaproblemhere.

Weneedtowritealloftheobjectsreachablefromtheoriginal

rootobject.Eachobjectmustbewrittenexactlyonce:wedon't

wanttomissany,andwedon'twanttowritetwocopiesofan

objectjustbecausetherearetworeferencestoit.



[Page474]

Handily,thisisexactlytheproblemsolvedbythecopying

garbagecollectordescribedinSection16.2.Javausesthis

algorithmtoconvertadirectedgraphofobjectsintoalinear

file,aprocesscalledserialization.Allwehavetodoismake

everyobjectwearesavingserializable.Wedothisby

implementingthejava.io.Serializableinterface.Thisinterface

hasnomethods;wemerelyhavetostatethatweare

implementingit.Manybuilt-inclasses,includingStringandall

ofthewrapperclasses,areSerializable.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 17. Out to the Disk

Tải bản đầy đủ ngay(0 tr)

×