版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
Java的輸入/輸出流7.1Java語言I/O的類層次Java輸入/輸出流封裝在包java.io中,其常用的層次結構如圖7.1、7.2所示。除了圖中給出的類外,實際使用中,我們還會碰到File類,它用來描述某個檔的資訊。輸入/輸出類中還有幾個比較重要的介面,例如:DataInput、DataOutput、FileNameFilter。後面我們會作詳細的介紹。圖7.1圖7.2Java的流方法從結構上可以分為三大類:位元組流、數(shù)據(jù)流和列印流。位元組輸入/輸出流操作對象為位元組(byte);數(shù)據(jù)流的數(shù)據(jù)比較多,包含所有基本類型的二進位數(shù)據(jù);列印流是機器能夠識別的字元形式(包括ASCII碼和Unicode碼)。7.2Java中文件的操作
編寫程式免不了要經(jīng)常與檔打交道,檔的輸入/輸出需要用到圖7.1中所列出的類FileInputStream、FileOutputStream及RandomAccessFile類。前兩個類針對於順序檔的存取,後一個類用於隨機檔的讀取。後面我們會有詳細的介紹。7.2.1檔與目錄的描述類——FileFile類並不用來進行檔的讀/寫操作,它用來描述檔對象的屬性,既可以表示檔,也可以表示目錄。使用它提供的方法,我們可以得到所指對象的描述資訊,包括名稱、存在否、讀/寫許可權、路徑等等。需要注意的是,當我們在Windows環(huán)境使用路徑時,其分隔符號不能是單一的“\”符號,因為與C/C++相同,符號“\”已經(jīng)被轉意了。例如:c:\jbuilder3\java\bin路徑是非法的,系統(tǒng)不會識別,正確的應該為c:\\jbilder3\\java\\bin下麵我們通過表7.1給出File類的一些方法及說明。表7.1File類的方法及變數(shù)方法及變數(shù)名功能描述publicFile(Filedir,Stringname)由指定的目錄、名字創(chuàng)建該對象publicFile(Stringpath,Stringname)由指定的路徑、名字創(chuàng)建該對象publicFile(Stringpath)由指定路徑創(chuàng)建該對象publicstaticfinalStringpathSeparator返回系統(tǒng)的路徑分隔符號publicbooleancanRead()如果檔可讀為真publicbooleancanWrite()如果檔可寫為真publicbooleandelete()刪除檔publicbooleanequals(Objectobj)檔比較,如是同一個檔則為真publicbooleanexists()指定的檔存在返回真publicStringgetAbsolutePath()得到檔的絕對路徑publicStringgetName()得到檔案名publicStringgetParent()得到父目錄的名字publicStringgetPath()返回路徑publicinthashCode()返回一個哈希碼publicnativebooleanisAbsolute()如果是絕對路徑返回真publicbooleanisDirectory()如果是目錄則返回真publicbooleanisFile()如果是檔則返回真publiclonglastModified()返回最近一次修改時間publiclonglength()返回檔長度publicString[]list(FilenameFilterfilter)返回指定格式的目錄中的檔案名publicString[]list()返回當前目錄中的所有檔案名publicbooleanmkdir()創(chuàng)建目錄,成功返回真publicbooleanmkdirs()創(chuàng)建路徑中所有目錄,成功則返回真publicstaticfinalcharpathSeparatorChar返回路徑分隔符號publicbooleanrenameTo(Filedest)檔更名,成功返回真publicstaticfinalcharseparatorChar返回檔分隔符號publicStringtoString()返回對象的字串表示
下麵我們給出幾個File類的應用實例。通過例題的使用,希望讀者對File類有更清楚的認識。例7.1importjava.io.*;publicclassMyClass1{
publicstaticvoidmain(Stringargs[]){
Filef=newFile("c:\\jbuilder3\\myprojects\\untitled5\\MyClass1.java");if(!f.exists())Transcript.println("FileMyClass1.javadoesn'texist!");else{Transcript.println("Thisfilecanread"+f.canRead());Transcript.println("lastmodified"+f.lastModified());Transcript.println("Parentis"+f.getParent());Transcript.println("Filelengthis"+f.length());}}publicMyClass1(){}}
該程式的運行結果如圖7.3所示。此程式中,我們?yōu)榱苏f明路徑分隔符號的使用方法,實例化檔對象的時候給出了全路徑,其實由於我們已經(jīng)在Java系統(tǒng)中設置好了源路徑,只要給出檔案名就行了。表7.1中,list方法用於列出一個目錄中所有的檔或與某個模式相匹配的檔。下麵我們給出兩個例子來討論帶參數(shù)或不帶參數(shù)的list方法的使用。圖7.3例7.2importjava.io.*;publicclassMyClass2{publicstaticvoidmain(Stringargs[]){Filef1=newFile("c:\\jbuilder3\\myprojects");if(!f1.isDirectory())Transcript.println("Error:"+f1+"isn'tadirectory!");else{StringdirList[]=f1.list();for(inti=0;i<dirList.length;i++)Transcript.println(dirList[i]);}
}}
publicMyClass2(){}}
在該例中,我們並沒有在調(diào)用File類的list方法中傳遞參數(shù),這樣,處在目錄c:\\jbuilder3\\myprojects下的所有檔及目錄將均被輸出,結果如圖7.4所示。
圖7.3圖7.4
程式設計中,往往會碰到根據(jù)某一匹配模式來查找目錄下的檔的問題,這時就需使用File類帶參數(shù)的list方法,即
publicString[]list(FilenameFilterfilter)
其中,參數(shù)FilenameFilter是一個介面,只有一個方法的定義:
booleanaccept(Filedir,Stringname);
對於指定目錄下的檔,我們可以調(diào)用該方法確定某個檔是否包含於其中。比如上例中,我們查找以“un”打頭的檔或目錄,程式如下:例7.3importjava.io.*;publicclassMyClass3implementsFilenameFilter{Filef;publicstaticvoidmain(Stringargs[]){Filef1=newFile("c:\\jbuilder3\\myprojects");if(!f1.isDirectory())Transcript.println("Error:"+f1+"isn'tadirectory!");else{MyClass3m=newMyClass3(f1);StringdirList[]=f1.list(m);for(inti=0;i<dirList.length;i++)Transcript.println(dirList[i]);}}publicMyClass3(Filef){this.f=f;}publicbooleanaccept(Filedir,Stringname){returnname.startsWith("un");}}7.2.2檔I/O處理
1.Byte流(位元組流)檔的讀取該類的結構如圖7.1所示,我們主要用其中的FileOutputStream和FileInputStream類,它們的父類為InputStream和OutputStream。主要的方法有:●InputStreamintread()
intread(bytebuf[])
intread(bytebuf[],intoffset,intlength)close()●OutputStreamintwrite(intc)intwrite(bytebuf[])intwrite(bytebuf[],intoffset,intlength)close()下麵給出一個應用實例7.4。圖7.5
例7.4
importjava.io.*;publicclassFileCopy{publicstaticvoidmain(Stringargs[])throwsIOException{FileInputStreamf1;FileOutputStreamf2;f1=newFileInputStream("FileCopy.java");f2=newFileOutputStream("acopy_of_java_file");
inttemp;while((temp=f1.read())!=-1)
f2.write(temp);
f1.close();f1.close();}
publicFileCopy(){}}
在該例中,我們利用位元組流將本程式拷貝至另一個檔acopy_of_java_file中,如果指定的檔不存在,則創(chuàng)建一個新檔,否則原文件的內(nèi)容會被新寫入的內(nèi)容覆蓋。當程式運行後,將生成一個與原程式相同的副本。2.Character流(字元流)檔的讀取該類如圖7.2所示,輸入/輸出類的父類為Reader、Writer,其基本的方法有:●Reader
intread()
intread(charbuf[])
intread(charbuf[],intoffset,intlength)close()●Writer
intwrite(intc)
intwrite(charbuf[])
intwrite(charbuf[],intoffset,intlength)close()
讀者可與位元組流進行比較,注意二者方法的區(qū)別。下麵我們用字符流來改寫例7.4:
例7.5
importjava.io.*;publicclassFileCopy{
publicstaticvoidmain(Stringargs[])throwsIOException{FileReaderf1;FileWriterf2;f1=newFileReader("FileCopy.java");f2=newFileWriter("acopy_of_java_file");inttemp;while((temp=f1.read())!=-1)f2.write(temp);f1.close();f2.close();}publicFileCopy(){}}例7.6importjava.io.*;publicclassReadFile{ publicstaticvoidmain(String[]args) throwsIOException{ FileReaderfr=newFileReader("ReadFile.java"); BufferedReaderbr=newBufferedReader(fr); Stringline=br.readLine(); while(line!=null){Transcript.println(line);
line=br.readLine(); } br.close();
}}
本程式中,我們通過類BufferedReader對檔實現(xiàn)按行讀取,達到一行一行輸出的目的,結果如圖7.6所示。圖7.63.二進位數(shù)據(jù)流的檔讀取如果要讀取與機器無關的基本數(shù)據(jù)類型的數(shù)據(jù),如整型或浮點型的二進位數(shù),就要用到二進位數(shù)據(jù)檔流DataInputStream、DataOutputStream。實際使用中,類DataInputStream和DataOutputStream必須和一個輸入類(InputStream)或輸出類(OutputStream)聯(lián)接起來,不能直接用檔案名或檔對象(File)對其直接初始化,例如:例7.7importjava.io.*;publicclassDatastreamDemo{publicstaticvoidmain(Stringargs[])throwsIOException{FileOutputStreamf2=newFileOutputStream("data");DataOutputStreamdfo=newDataOutputStream(f2);dfo.writeBoolean(true);
dfo.writeInt(100);dfo.writeFloat(200.2f);f2.close();dfo.close();FileInputStreamf1=newFileInputStream("data");DataInputStreamdfi=newDataInputStream(f1);booleanb=dfi.readBoolean();inti=dfi.readInt();floatf=dfi.readFloat();f1.close();dfi.close();Transcript.println("Thevalueis:");Transcript.println(""+b);Transcript.println(""+i);Transcript.println(""+f);}
publicDatastreamDemo(){}}
該例中,我們首先利用類DataOutputStream生成一個二進位檔data,並對它寫入三個不同類型的數(shù)據(jù):布爾型、整型、浮點型。然後利用DataInputStream讀入剛剛輸入的數(shù)據(jù)並顯示出來,結果如圖7.7所示??梢钥闯觯敵鼋Y果與我們的輸入是一一對應的。圖7.74.隨機訪問檔的讀取對於InputStream/OutputStream、Reader/Writer類來說,它們都是順序訪問流,只能進行順序讀寫。而所謂隨機讀寫,是指讀寫完上一個位元組後,不只能讀寫其後繼的位元組,還可以讀寫檔中任意的位元組,就好象檔中有一個隨意移動的指針一樣。
Java語言提供了類RandomAccessFile來進行隨機檔的讀取。在生成一個RandomAccessFile對象時,不僅要說明文件對象或檔案名,同時還需指明訪問模式,即“只讀方式”(r)或“讀寫方式”(rw),這類似於C/C++中的fopen()函數(shù)。
RandomAccessFile類的功能類似於DataOutputStream類和DataInputStream類的功能合併,即實現(xiàn)了在一個流中進行讀、寫兩種功能。其常用的方法如表7.2所示。表7.2RandomAccessFile類的常用方法方法名功能描述longgetFilePointer()返回當前檔指針longlength()返回檔長度booleanreadBoolean()讀入一個布爾值intreadInt()讀入一個整數(shù)stringreadLine()讀入一行字串voidseek(longpos)檔指針移到指定位置intskipBytes(intn)檔指針向前移n個位元組voidwrite(byteb[])把數(shù)組內(nèi)容寫入檔voidwriteBoolean(booleanv)寫入一個布爾值voidwriteInt(intv)寫入一個整數(shù)
例7.8的功能與例7.7一樣,只不過是用RandomAccessFile來實現(xiàn)的。例7.8importjava.io.*;publicclassRandomDemo{publicstaticvoidmain(Stringargs[])throwsIOException{RandomAccessFilefa=newRandomAccessFile("data","rw");
fa.writeBoolean(true);fa.writeInt(100);fa.writeFloat(200.2f);fa.seek(0);booleanb=fa.readBoolean();inti=fa.readInt();floatf=fa.readFloat();Transcript.println("Thevaluereadfromarandomfileis:");Transcript.println(""+b);Transcript.println(""+i);Transcript.println(""+f);
fa.close();}publicRandomDemo(){}}程式運行結果如圖7.8所示。圖7.87.3特殊的I/O處理流
除了前面我們介紹的一些常用的輸入/輸出流之外,java.io包中提供了很多特殊的輸入/輸出流,我們可描述如表7.3所示。類型說明流類功能描述管道流PipedReaderPipedWriterPipedInputStreamPipedOutputStream用於在不同的線程或進程之間進行資訊傳遞記憶體流CharArrayReaderCharArrayWriterByteArrayInputStreamByteArrayOutputStream用於在內(nèi)存中進行讀/寫,往往借助於數(shù)組,通過read()或write()方法從數(shù)組中讀/寫數(shù)據(jù)StringReaderStringWriterStringBufferInputStream從存在於記憶體的一個字串中讀/寫數(shù)據(jù)輸入流的連接SequenceInputStream將多個InputStream連接起來順序進行輸入過濾流FilterReaderFilterWriterFilterInputStreamFilterOutputStream特定的抽象類,須擴展解析流StreamTokenizer用於對字串的解析表7.3java.io包中的特殊輸入/輸出流表7.3java.io包中的特殊輸入/輸出流7.3.1管道流管道流(PipedStream)可用來把一個程式、線程或代碼段的輸出直接連接到另一個程式、線程或代碼段的輸入。Java中管道的類有PipedReader、PipedWriter、PipedInputStream及PipedOutputStream。使用過程中,管道輸入流作為一個通信管道的接收端進行數(shù)據(jù)的讀取,管道輸出流作為發(fā)送端進行數(shù)據(jù)的傳送。下麵我們先看一個實例:例7.9importjava.io.*;publicclassPipedDemo{publicstaticvoidmain(Stringargs[])throwsIOException{PipedWriterpw=newPipedWriter();PipedReaderpr=newPipedReader(pw);newRead(pw,"ReadFile.txt").start();newWrite(pr,"WriteFile.txt").start();}publicPipedDemo(){ }}importjava.io.*;publicclassWriteextendsThread{PipedReaderpr;Filef;Write(PipedReaderpr,Stringf){this.pr=pr;this.f=newFile(f);}publicvoidrun(){try{FileWriterfw=newFileWriter(f);
intdata;while((data=pr.read())!=-1)fw.write(data);fw.close();}catch(IOExceptione){}}publicWrite(){}}importjava.io.*;publicclassReadextendsThread{PipedWriterpw;Filef;Read(PipedWriterpw,Stringf){this.pw=pw;this.f=newFile(f);}
publicvoidrun(){try{FileReaderfr=newFileReader(f);intdata;while((data=fr.read())!=-1)pw.write(data);pw.close();}catch(IOExceptione){}}
在本例中,我們通過定義兩個線程進行管道PipedReader、PipedWriter的連接。線程的概念讀者可參考後面章節(jié)的內(nèi)容,這裏只要把其理解為可以同時工作的兩段程式就可以了。程式運行後,WriteFile.txt的內(nèi)容就從檔ReadFile.txt中完全拷貝過來。在管道流的初始化過程中,可以給出對應的管道輸入/輸出流作為參數(shù)進行連接,如本例:
PipedReaderpr=newPipedReader(PipedWriterpw);
或 PipedWriterpw=newPipedWriter(PipedReaderpr);
在Java中,管道輸入/輸出流還可以通過方法connect()進行連接,如把本例中的程式改為
PipedWriterpw=newPipedWriter();PipedReaderpr=newPipedReader(); pr.connect(pw);
效果是一樣的。讀者也可用管道流PipedInputStream、PipedOutputStream來實現(xiàn)上例,這裏留給讀者自己練習。7.3.2記憶體的I/O流表7.3給出了Java支持記憶體讀/寫的類,總結起來有以下兩類。
(1)對應位元組記憶體讀/寫的有ByteArrayInputStream、ByteArrayOutputStream及String
BufferInputStream。它們可以從位元組數(shù)組中讀取數(shù)據(jù)或向位元組數(shù)組中寫入數(shù)據(jù)。例如:例7.10importjava.io.*;publicclassMemoryDemo{publicstaticvoidmain(Stringargs[])throwsIOException{byteb[]={111,100,74,98,80,69};bytetemp[]=newbyte[10];ByteArrayInputStreambi=newByteArrayInputStream(b);ByteArrayOutputStreambo=newByteArrayOutputStream();StringBufferInputStreambs=newStringBufferInputStream("Ademoformemoryinput!");intx;while((x=bi.read())!=-1)
bo.write(x);Transcript.println("TheresultofByteArrayOutputStreamis:"+bo);bs.read(temp,0,4);Transcript.print("TheresultofStringBufferOutputStreamis:");for(inti=0;i<=3;i++)Transcript.print(""+temp[i]);Transcript.println();Transcript.print(""+bs);}}
運行結果如圖7.9所示。圖7.9
對於ByteArrayOutputStream來說,我們先從ByteArrayInputStream類中把位元組流讀入bo的緩衝區(qū)中,然後直接進行輸出,該對象調(diào)用自己的toString()進行輸出格式轉換。
(2)對應字元記憶體讀/寫的有CharArrayReader、CharArrayWriter、StringReader及StringWriter。它們可以從字元數(shù)組中讀取數(shù)據(jù)或向字元數(shù)組中寫入數(shù)據(jù)。例如:例7.11
importjava.io.*;publicclassMemoryDemo{publicstaticvoidmain(Stringargs[])throwsIOException{charb[]={'a','t','e','s','t','d','e','m','o'};chartemp[]=newchar[10];CharArrayReaderbr=newCharArrayReader(b);CharArrayWriterbw=newCharArrayWriter();StringReaderbsr=newStringReader("testdemo!");StringWriterbsw=newStringWriter();intx;while((x=br.read())!=-1)bw.write(x);Transcript.println("TheresultofCharArrayReaderis:"+bw);bsr.read(temp,0,4);Transcript.print("TheresultofStringReaderis:");for(inti=0;i<=3;i++)Transcript.print(""+temp[i]);Transcript.println();bsw.write("hello,everybody!");Transcript.print("TheresultofStringWriteris:");Transcript.println(""+bsw);}}
程式運行結果如圖7.10所示。圖7.10
我們可以發(fā)現(xiàn)以上兩個程式的基本架構無大的區(qū)別,只是對不同記憶體流,構造方法有所不同。上述的幾種輸出記憶體流,它們在初始化的時候,缺省的緩衝區(qū)的大小均為32個位元組。當然,實際操作過程中,緩衝區(qū)的大小會隨數(shù)據(jù)的寫入自動增加。不同的類會有多種不同的方法,方法的使用建立在對各種流的熟悉程度之上,讀者應盡可能的學習Java聯(lián)機文檔的內(nèi)容,獲取更多的知識。7.3.3多個輸入流的連接如果我們在對檔的操作中需要讀取多個檔的話,可使用Java所提供的SequenceInputStream類。該類把多個檔連接起來,形成多個連接的順序輸入流,該流依次打開每個輸入流,讀取數(shù)據(jù),然後關閉該流,並自動切換到下一個輸入流。它的兩種構造方法如下:
SequenceInputStream(Enumeratione); SequenceInputStream(InputStreams1,InputStreams2);其中,Enumeration類為一介面,處在Java中的util包中,它包含兩個方法:
publicObjectnextElement() publicbooleanhasMoreElements()
方法nextElement()取得集合中的下一個對象;方法hasMoreElements()測試集合中的元素是否已經(jīng)全部取完,並返回一個布爾值。下麵是一個利用順序流對指定的兩個檔進行合併操作的例子。例7.12importjava.io.*;importjava.util.*;publicclassConcaDemo{publicstaticvoidmain(Stringargs[])throwsIOException{Strings[]=newString[2];s[0]="PipedDemo.java";s[1]="MemoryDemo.java";Filesflist=newFiles(s);SequenceInputStreamsi=newSequenceInputStream(flist);FileOutputStreamfo=newFileOutputStream("concaFile.txt");intc;while((c=si.read())!=-1)fo.write(c);si.close();fo.close();}}importjava.io.*;importjava.util.*;publicclassFilesimplementsEnumeration{privateString[]listofFiles;privateintcurrent=0;publicFiles(String[]listofFiles){this.listofFiles=listofFiles;}publicbooleanhasMoreElements(){if(current<listofFiles.length)returntrue;elsereturnfalse;}publicObjectnextElement(){try{if(!hasMoreElements())returnnull;else{current++;returnnewFileInputStream(listofFiles[current-1]);}}catch(Exceptione){returnnull;}
}}
當我們在JBuilder中運行該程式後,檔concaFile.txt就合併了PipedDemo.java及MemoryDemo.java中的內(nèi)容。7.3.4過濾流過濾流在讀/寫數(shù)據(jù)的同時可以對數(shù)據(jù)進行處理。Java提供了多個具有過濾功能的輸入/輸出類,位元組類過濾流的父類均為FilterInputStream、FilterOutputStream。這兩個類為抽象類,包含的子類有:
DataInputStream/DataOutputStreamBufferedInputStream/BufferedOutputStreamLineNumberInputStreamPushbackInputStreamPrintStream
FilterReader/FilterWriter
過濾流是建立在其他流之上的,也就是說,當使用一個過濾流時,必須首先把過濾流連接到某個輸入/輸出流上。比如,可以通過輸入過濾流的方法read()從下層流中讀取數(shù)據(jù),通過輸出過濾流的write()方法把數(shù)據(jù)寫入下層流。
不同過濾流實現(xiàn)不同的過濾功能,例如:數(shù)據(jù)的暫存、數(shù)據(jù)的統(tǒng)計、數(shù)據(jù)的轉換等等。讀者對上述的一些類也不必死記,使用的時候,查看相關的聯(lián)機幫助文檔便可獲得詳細的內(nèi)容。下麵我們分兩部分來對過濾流加以介紹:首先介紹如何使用Java系統(tǒng)提供的過濾流類,之後,介紹如何定義自己的過濾流。1.使用過濾流類BufferedInputStream/BufferedOutputStream實現(xiàn)了帶緩衝的過濾流。進行網(wǎng)路編程時,當需要在不同線程之間傳送數(shù)據(jù)時,使用緩衝流會得到較高的性能。數(shù)據(jù)的輸入/輸出均是首先讀入/寫出到緩衝區(qū)中,對BufferedOutputStream來說,當數(shù)據(jù)緩衝區(qū)滿時,就可以寫入所連接的輸出流,它所提供的flush()也可強制緩衝區(qū)的內(nèi)容在任何時候全部寫入輸出流。
過濾流DataInputStream、DataOutputStream實現(xiàn)了介面DataInput、DataOutput。它們可以從所連接的輸入流中讀取與機器無關的基本數(shù)據(jù)類型,也可以向所連接的輸出流寫入基本類型數(shù)據(jù)。這一點我們可以從例7.7看出。類PrintStream所提供的方法print()、println()可以輸出各種類型數(shù)據(jù),只是後一種方法在輸入結束時自動換行。我們可以利用生成該類的實例進行不同數(shù)據(jù)的輸出。下麵我們給出應用過濾流的具體實例:
例7.13importjava.io.*;publicclassFilterIODemo{publicstaticvoidmain(Stringargs[])throwsIOException{DataInputStreamdi=newDataInputStream(newBufferedInputStream(System.in));PrintStreampo=newPrintStream(newBufferedOutputStream(System.out));Strings;s=di.readLine();while(!s.equals("seeyou!")){po.println("Result:"+s);po.flush();s=di.readLine();}di.close();po.close();}publicFilterIODemo(){}}
本例中,System.in、System.out是系統(tǒng)的標準輸入/輸出類,這裏我們指的是控制臺,即鍵盤和螢幕。該段程式運行時,用戶可不斷輸入一些字元,輸入的字元會立即顯示在螢幕上,直到某一行輸入的字元中有“seeyou!”時,程式結束運行。結果如圖7.11所示。圖7.11例7.14
importjava.io.*;publicclassPushbackDemo{publicstaticvoidmain(Stringargs[])throwsIOException{PushbackInputStreampis=newPushbackInputStream(System.in);intdata;data=pis.read();while(!Character.isLetter((char)data))data=pis.read();pis.unread(data);while(true){data=pis.read();if(Character.isLetter((char)data))Transcript.print(""+(char)data);}}publicPushbackDemo(){}}
程式中語句:
while(!Character.isLetter((char)data))
data=pis.read();
pis.unread(data);
的作用是把開頭的白字符(whitecharacter)過濾掉,並且回吐給輸入流過濾掉的第一個字元。2.創(chuàng)建自己的過濾流程式的編寫過程中,往往需要實現(xiàn)自己的過濾流以在讀/寫操作時可以對數(shù)據(jù)進行特定的處理,這時就必須自己定義繼承於FilterInputStream、FilterOutputStream的過濾流。如果有必要,需重載方法read()、write()或其他一些方法,同時應該確保輸入/輸出流一起工作。請看下例。例7.15
importjava.io.*;publicclassMain{publicstaticvoidmain(Stringargs[])throwsIOException{InputStreamfin=newFileInputStream("ReadFile.txt");OutputStreamstdout=newFileOutputStream(FileDescriptor.out);MyInputStreamnis=newMyInputStream(fin);MyOutputStreamnos=newMyOutputStream(stdout);while(true)nos.write(nis.read());}publicMain(){}}importjava.io.*;publicclassMyInputStreamextendsFilterInputStream{publicintread()throwsIOException{
intdata=in.read();StringBuffersb=newStringBuffer();while(data!=-1&&!Character.isDigit((char)data))data=in.read();while(data!=-1&&Character.isDigit((char)data)){sb.append((char)data);data=in.read();}returnInteger.parseInt(sb.toString());}publicMyInputStream(InputStreamin){super(in);}}importjava.io.*;publicclassMyOutputStreamextendsFilterOutputStream{publicvoidwrite(intb)throwsIOException{System.out.println("NowinOutputStreamis:");Stringdata=Integer.toString(b);bytechar_array[]=newbyte[data.length()];data.getBytes(0,data.length(),char_array,0);out.write(char_array);}publicMyOutputStream(OutputStreamout){super(out);}}
本例中,定義了兩個類:MyInputStream和MyOutputStream,它們均從過濾流FilterInputStream、FilterOutputStream繼承而來,同時重寫了父類中的read()、write()方法。在類MyInputStream的read()方法中,可以讀出檔中所有的數(shù)字運算式。因為我們並沒有對所有的例外進行捕獲,所以,類Main中的語句“while(true)”雖是無限迴圈,但最終卻能由例外NumberFormatException中斷。在類MyOutputStream中,由於沒有相關的輸出字元方法,如DataInputStream中的writeChar()方法,因而我們首先把數(shù)字轉換為一個位元組數(shù)組,然後進行輸出。假如檔ReadFile.txt的內(nèi)容為Number:124589100 Score:65892288則最後的輸出結果為SystemOutput: NowinOutputStreamis:SystemOutput: 12SystemOutput: NowinOutputStreamis:SystemOutput: 45SystemOutput: NowinOutputStreamis:SystemOutput: 89SystemOutput: NowinOutputStreamis:SystemOutput: 100SystemOutput: NowinOutputStreamis:SystemOutput: 65SystemOutput: NowinOutputStreamis:SystemOutput: 89SystemOutput: NowinOutputStreamis:SystemOutput: 22SystemOutput: NowinOutputStreamis:SystemOutput: 887.3.5解析流
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度2025年度藝人教育培訓課程開發(fā)合同2篇
- 2025年白銀有色集團股份有限公司招聘筆試參考題庫含答案解析
- 如何提高餐廳的客流量
- 2025年西安西電電力系統(tǒng)有限公司招聘筆試參考題庫含答案解析
- 2025年湖北恩施州恩施市花沐蘭園林綠化有限公司招聘筆試參考題庫附帶答案詳解
- 2025年粵教版九年級歷史上冊月考試卷
- 2025年人教版必修3物理上冊月考試卷
- 2025年統(tǒng)編版必修3歷史下冊月考試卷含答案
- 2025年度木質家具組裝木工勞務承包合同4篇
- 2025年蘇人新版選修3歷史下冊階段測試試卷
- 項目前期選址分析報告
- 急性肺栓塞搶救流程
- 《統(tǒng)計學-基于Python》 課件全套 第1-11章 數(shù)據(jù)與Python語言-時間序列分析和預測
- 《形象價值百萬》課件
- 紅色文化教育國內(nèi)外研究現(xiàn)狀范文十
- 中醫(yī)基礎理論-肝
- 小學外來人員出入校門登記表
- 《土地利用規(guī)劃學》完整課件
- GB/T 25283-2023礦產(chǎn)資源綜合勘查評價規(guī)范
- 《汽車衡全自動智能稱重系統(tǒng)》設計方案
- 義務教育歷史課程標準(2022年版)
評論
0/150
提交評論