JAVA輸入與輸出處理_第1頁
JAVA輸入與輸出處理_第2頁
JAVA輸入與輸出處理_第3頁
JAVA輸入與輸出處理_第4頁
JAVA輸入與輸出處理_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第五講輸入與輸出處理

I/O流概述

字節(jié)流字節(jié)流的基類文件流過濾流標準流

字符流對象流管道流內存讀寫流順序輸入流I/O流概述大部分程序都需要輸入/輸出處理,比如從鍵盤讀取數據、向屏幕中輸出數據、從文件中讀或者向文件中寫數據、在一個網絡連接上進行讀寫操作等。在Java中,把這些不同類型的輸入、輸出源抽象為流(Stream),而其中輸入或輸出的數據則稱為數據流(DataStream),用統(tǒng)一的接口來表示,從而使程序設計簡單明了。文件程序終端文件程序網絡端點數據流起點終點

網絡端點文件,字符串存儲區(qū)I/O流概述流一般分為輸入流(InputStream)和輸出流(OutputStream)兩類,但這種劃分并不是絕對的。比如一個文件,當向其中寫數據時,它就是一個輸出流;當從其中讀取數據時,它就是一個輸入流。當然,鍵盤只是一個輸人流,而屏幕則只是一個輸出流。在Java開發(fā)環(huán)境中,主要是由包java.io中提供的一系列的類和接口來實現(xiàn)輸入/輸出處理。標準輸入/輸出處理則是由包java.lang中提供的類來處理的,但這些類又都是從包java.io中的類繼承而來?;綢/O操作原理讀打開一個流對象->當未到結尾處時,從流中讀入信息->關閉流對象寫:打開一個流對象->當未到結尾處時,向流中寫入信息->關閉流對象I/O流概述I/O流概述在JDK1.1之前,java.io包中的流只有普通的字節(jié)流(以byte為基本處理單位的流),這種流對于以16位的Unicode碼表示的字符流處理很不方便。從JDK1.1開始,java.io包中加入了專門用于字符流處理的類(以Reader和Writer為基礎派生的一系列類)。

另外,為了使對象的狀態(tài)能夠方便地永久保存下來,JDK1.1以后的java.io包中提供了以字節(jié)流為基礎的用于對象的永久化保存狀態(tài)的機制(通過實現(xiàn)ObjectInput和ObjectOutput接口)。字節(jié)流 ——基類

Java中每一種字節(jié)流的基本功能依賴于基本類InputStream和OutputStream,它們是抽象類,不能直接使用。屬于InputStream類的方法有:

read():從流中讀入數據

skip():跳過流中若干字節(jié)數

available():返回流中可用字節(jié)數

mark():在流中標記一個位置

reset():返回標記過得位置

markSupport():是否支持標記和復位操作

close():關閉流字節(jié)流 ——基類在InputStream類中,方法read()提供了三種從流中讀數據的方法:

intread():從輸入流中讀一個字節(jié),形成一個0~255之間的整數返回(是一個抽象方法)。

intread(byteb[]):讀多個字節(jié)到數組中,填滿整個數組。

intread(byteb[],intoff,intlen):從輸入流中讀取長度為len的數據,寫入數組b中從索引off開始的位置,并返回讀取得字節(jié)數。對于這三個方法,若返回-1,表明流結束。字節(jié)流 ——基類

屬于OutputStream類的方法有:

write(intb):將一個整數輸出到流中(只輸出低位字節(jié),為抽象方法)

write(byteb[]):將字節(jié)數組中的數據輸出到流中

write(byteb[],intoff,intlen):將數組b中從off指定的位置開始,長度為len的數據輸出到流中

flush():刷空輸出流,并將緩沖區(qū)中的數據強制送出

close():關閉流Writer的方法:

write(Strings),write(Strings,intoff,intlen)BufferedInputStream和BufferedOutputStream為輸入輸出流創(chuàng)建和維持緩沖。緩沖是一種提高讀寫效率的機制。DataInputStream和DataOutputStreamDataInputStreamreadBoolean()讀一字節(jié),非零為真readByte()以8位讀字節(jié)readChar()讀Unicode字符readInt()讀整數值DataOutputStreamwriteChar(intv)把字符寫進輸出流writeLong(longv)把長整寫進輸出流writeInt(intv)把整數寫進輸出流PipedInputStream和PipedOutputStream管道用于在線程之間傳輸數據。在線程里的PipedInputStream對象從出現(xiàn)在另一個線程里的PipedOutputStream對象接收輸入。<在線程里講>DataInputStream和DataOutputStream允許你讀和寫java對象。readObject()writeObject()字節(jié)流 ——文件流在I/O處理中,最常見的就是對文件的操作。java.io包中所提供的文件操作類包括:File:FileDescriptor:FilenameFilter:接口,主要用于實現(xiàn)文件名查找模式的匹配。FileInputStream:FileOutputStream:RandomAccessFile:提供對本地文件系統(tǒng)中文件的隨機訪問支持。描述本地文件系統(tǒng)中的文件或目錄用于讀寫本地文件系統(tǒng)中的文件字節(jié)流 ——文件流:File使用文件類File可以獲取文件的各種信息。

Filef=newFile(“data\temp.dat”);f.getName():返回文件名temp.datf.getParent():返回文件所在目錄名dataf.getPath():返回文件路徑data\temp.datf.getAbsolutePath():返回絕對路徑…\data\temp.datf.exists():文件是否存在f.canWrite(),f.canRead():文件是否可寫、讀f.isFile(),f.isDirectory():是否為文件或目錄f.lastModified(),f.length(),f.delete():

文件的最后修改日期、長度;刪除文件f.mkdir(),f.list():創(chuàng)建一個目錄;列出目錄下所有的文件字節(jié)流 ——文件流:FileInputStream/FileOutputStream

FileInputStream類用來打開一個輸入文件,若要打開的文件不存在,則會產生例外FileNotFoundException,這是一個非運行時例外,必須捕獲或聲明拋棄;

FileOutputStream類用來打開一個輸出文件,若要打開的文件不存在,則會創(chuàng)建一個新的文件,否則原文件的內容會被新寫入的內容所覆蓋。在進行文件的讀/寫操作時,會產生非運行時例外IOException,必須捕獲或聲明拋棄(其它的輸入/輸出流處理時也同樣需要進行輸入/輸出例外處理)。字節(jié)流 ——文件流:FileInputStream/FileOutputStream文件流的建立:

Filef1=newFile(“file1.txt”);Filef2=newFile(“file2.txt”);

FileInputStreamin=newFileInputStream(f1);

FileOutputStreamout=newFileOutputStream(f2);

FileOutputStreamout=newFileOutputStream(“file3.txt”);輸入流的參數是用于指定輸入的文件名,輸出流的參數則是用于指定輸出的文件名。輸出文件輸入文件readwrite字節(jié)流——文件流

importjava.io.*;classFilestream

{

publicstaticvoidmain(Stringargs[]){

try{FileinFile=newFile("file1.txt");

FileoutFile=newFile("file2.txt");

FileInputStreamfis=newFileInputStream(inFile);

FileOutputStreamfos=newFileOutputStream(outFile);

intc;

while((c=fis.read())!=-1)fos.write(c);

fis.close();

fos.close(); }catch(FileNotFoundExceptione){ System.out.println("FileStreamsTest:"+e); }catch(IOExceptione){ System.err.println("FileStreamsTest:"+e); }}}字節(jié)流 ——文件流:RandomAccessFile對于InputStream和OutputStream來說,它們的實例都是順序訪問流,即只能進行順序讀/寫。而類RandomAccessFile則允許對文件內容同時完成讀和寫操作,它直接繼承object,并且同時實現(xiàn)了接口DataInput和DataOutput,提供了支持隨機文件操作的方法:

readXXX()或writeXXX():

如ReadInt(),ReadLine(),WriteChar(),WriteDouble()等。

intskipBytes(intn):將指針鄉(xiāng)下移動若干字節(jié)

length():返回文件長度

longgetFilePointer():返回指針當前位置

voidseek(longpos):將指針調到所需位置posfile在生成一個隨機文件對象時,除了么指明文件對象和文件名之外,還需要指明訪問文件的模式。Filef=newFile(“file.txt”);newRandomAccessFile(f,“r”);newRandomAccessFile(f,“rw”);newRandomAccessFile(“file1.txt”,“r”);newRandomAccessFile(“file2.txt”,“rw”);字節(jié)流 ——文件流:RandomAccessFilepublicclassrandom_file{publicstaticvoidmain(Stringargs[]){

intdata_arr[]={12,31,56,23,27,1,43,65,4,99};try

{

RandomAccessFilerandf=newRandomAccessFile(“temp.dat”);for(inti=0;i>data_arr.length;i++)randf.writeInt(data_arr[i]);for(inti=data_arr.length-1;i>=0;i--){

randf.seek(i*4);System.out.println(randf.readInt());

}randf.close();}catch(IOExceptione){

System.out.println(“Fileaccesserror:“+e);}}}字節(jié)流——文件流字節(jié)流 ——過濾流

java.io中提供類FilterInputStream和FilterOutputStream分別對其他輸入/輸出流進行特殊處理,它們在讀/寫數據的同時可以對數據進行特殊處理。另外還提供了同步機制,使得某一時刻只有一個線程可以訪問一個輸入/輸出流。類FilterInputStream和FilterOutputStream分別重寫了父類InputStream和OutputStream的所有方法,同時,它們的子類也應該重寫它們的方法以滿足特定的需要。要使用過濾流,首先必須把它連接到某個輸入/輸出流上,通常在構造方法的參數中指定所要連接的流:

FilterInputStream(InputStreamin);

FilterOutputStream(OutputStreamout);字節(jié)流 ——過濾流:緩沖流類BufferedInputStream和BufferedOutputStream實現(xiàn)了帶緩沖的過濾流,它提供了緩沖機制,把任意的I/O流“捆綁”到緩沖流上,可以提供該I/O流的讀取效率。在初始化時,除了要指定所連接的I/O流之外,還可以指定緩沖區(qū)的大小。缺省時實用32字節(jié)大小的緩沖區(qū);最優(yōu)的緩沖區(qū)大小常依賴于主機操作系統(tǒng)、可使用的內存空間以及機器的配置等;一般緩沖區(qū)的大小為內存頁或磁盤塊等地整數倍,如8912字節(jié)或更小。字節(jié)流 ——過濾流:緩沖流將緩沖流與文件流相接:FileInputStreamin=newFileInputStream(“file1.txt”);FileOutputStreamout=newFileOutputStream(“file2.txt”);BufferedInputStreambin=newBufferedInputStream(in,256)BufferedOutputStreambout=newBufferedOutputStream(out,256);intlen;bytebArray[]=newbyte[256];len=bin.read(bArray);//len中得到是長度,bArray中得到的是數據

對于BufferedOutputStream,只有緩沖區(qū)滿時,才會將數據真正送到輸出流,但可以使用flush()方法人為地將尚未填滿的緩沖區(qū)中的數據送出。file1.txtfile2.txt輸入流輸出流輸入緩沖流輸出緩沖流文件文件流緩沖流字節(jié)流 ——過濾流:數據流數據流類DataInputStream和DataOutputStream的處理對象除了是字節(jié)或字節(jié)數組外,還可以實現(xiàn)對文件的不同數據類型的讀寫。它們分別實現(xiàn)了接口DataInput和DataOutput(與RandomAccessFile類似),提供了一種較為高級的數據輸入輸出方式:除了可處理字節(jié)和字節(jié)數組外,還可以處理int、float、boolean等基本數據類型,這些數據在文件中的表示方式和它們在內存中的一樣,無須轉換,如read(),readInt(),readByte()…;write(),writeChar(),writeBoolean()…。此外,還可以用readLine()方法讀取一行信息。字節(jié)流 ——過濾流:數據流數據輸出流可以是一個已經建立好的輸入數據流對象,例如網絡的連結,文件等。數據流可通過如下方式建立:FileInputStreamfis=newFileInputStream("file1.txt");FileOutputStreamfos=newFileOutputStream("file2.txt");DataInputStreamdis=newDataInputStream(fis);DataOutputStreamdos=newDataOutputStream(fos);classdatainput_output{

publicstaticvoidmain(Stringargs[])throwsIOException

{

FileOutputStreamfos=newFileOutputStream(“a.txt”);DataOutputStreamdos=newDataOutputStream(fos);try{

dos.writeBoolean(true);

dos.writeByte((byte)123);

dos.writeChar('J');

dos.writeDouble(3.141592654);

dos.writeFloat(2.7182f);

dos.writeInt(1234567890);

dos.writeLong(998877665544332211L);

dos.writeShort((short)11223);}finally{

dos.close();

}FileInputStreamfis=newFileInputStream("a.txt")DataInputStreamdis=newDataInputStream(fis);try{

System.out.println("\t"+dis.readBoolean());System.out.println("\t"+dis.readByte());System.out.println("\t"+dis.readChar());System.out.println("\t"+dis.readDouble());System.out.println("\t"+dis.readFloat());System.out.println("\t"+dis.readInt());System.out.println("\t"+dis.readLong());System.out.println("\t"+dis.readShort());}finally{dis.close();}}//main()}//classdatainput_output字節(jié)流 ——過濾流:數據流//利用方法readLine()計算一個輸入流中的字符數和行數//(適合于文本文件)DataLine(InputStreamin){

DataInputStreamdata=newDataInputStream(in);StringcurrentLine;intlineCount=0;

intcharCount=0;while((currentLine=data.readLine())!=null){++lineCount;charCount+=currentLine.length();}return(charCount/(float)lineCount);}字節(jié)流 ——過濾流:其他過濾流LineNumberInputStream:主要用于對文本文件的處理,提供了行號控制功能。PushBackInputStream:在編譯程序的詞法分析階段,經常要超前讀入一個字節(jié)以界定當前詞的屬性,然后再將該字節(jié)退回(因為下面的處理可能還會用到該字節(jié))。PushBackInputStream就提供了這樣的能力,它提供了一個方法將剛剛讀入的字節(jié)退回到輸入流中去。PrintStream:其作用是將Java語言中的不同類型的數據以字符表示形式輸出到相應的輸出流中去。字節(jié)流 ——標準流語言包java.lang中的System類管理標準輸入/輸出流和錯誤流。

System.in,從InputStream中繼承而來,用于從標準輸入設備中獲取輸入數據(通常是鍵盤)。

System.out,從PrintStream中繼承而來,把輸出送到缺省的顯示設備(通常是顯示器)。

System.err,也是從PrintStream中繼承而來,把錯誤信息送到缺省的顯示設備(通常是顯示器)。每當main方法被執(zhí)行時,就自動生成上述三個對象。publicclassReadFromKB{publicstaticvoidmain(Stringargs[]){try{ bytebArray[]=newbyte[128]; Stringstr; System.out.println("EntersomethingUsingKeyborad:"); System.in.read(bArray); str=newString(bArray,0); System.out.print("Youentered:"); System.out.println(str);}catch(IOExceptionioe){ System.out.println(ioe.toString());}}}字節(jié)流 ——對象流對象的持續(xù)性(persistence)

能夠紀錄自己的狀態(tài)以便將來再生的能力,叫對象的持續(xù)性。對象的串行化(Serialization)

對象通過寫出描述自己狀態(tài)的的數值來記錄自己的過程叫串行化。串行化的主要任務是寫出對象實例變量的數值,如果變量是另一個對象的引用,則引用的對象也要串行化。這個過程是遞歸的。對象流能夠輸入輸出對象的流稱為對象流??梢詫ο蟠谢笸ㄟ^對象輸入輸出流寫入文件或傳送到其它地方。字節(jié)流 ——對象流在java中,允許可串行化的對象在通過對象流進行傳輸。只有實現(xiàn)Serializable接口的類才能被串行化,Serializable接口中沒有任何方法,當一個類聲明實現(xiàn)Serializable接口時,只是表明該類加入對象串行化協(xié)議。publicclassStudentimplementsSerializable{

intid;Stringname;

intage;Stringdepartment;publicStudent(intid,Stringname,intage,Stringdepartment){

this.id=id;

=name;this.age=age;

this.department=departmernt;}}字節(jié)流 ——對象流要串行化一個對象,必須與一定的對象輸出/輸入流聯(lián)系起來,通過對象輸出流將對象狀態(tài)保存下來(將對象保存到文件中,或者通過網絡傳送到其他地方),再通過對象輸入流將對象狀態(tài)恢復。類ObjectOutputStream和ObjectInputStream分別繼承了接口ObjectOutput和ObjectInput,將數據流功能擴展到可以讀寫對象,前者用writeObject()方法可以直接將對象保存到輸出流中,而后者用readObject()方法可以直接從輸入流中讀取一個對象。publicclassObjectser{publicstaticvoidmain(Stringargs[]){Studentstu=newStudent(981036,“LiMing”,16,“CSD”);try

{

FileOutputStreamfo=newFileOutputStream(“data.ser”);ObjectOutputStreamso=newObjectOutputStream(fo);

so.writeObject(stu);so.close();}catch(Exceptione)

{System.out.println(e);}}}publicclassObjectRecov{

publicstaticvoidmain(Stringargs[]){

Studentstu;try

{

FileInputStreamfi=newFileInputStream(“data.ser”);ObjectInputStreamsi=newObjectInputStream(fi);stu=(Student)si.readObject();

si.close();}catch(Exceptione)

{System.out.println(e);}System.out.println(“ID:”+stu.id+“name:”++“age:”+age+“dept.:”+stu.department);}}publicclassStudentimplementsSerializable{intid;Stringname;intage;Stringdepartment;publicStudent(intid,Stringname,intage,Stringdepartment){this.id=id;=name;this.age=age;this.department=departmernt;}privatevoidwriteObject(ObjectOutputStreamout)throwsIOException

{ out.writeInt(id); …}privatevoidreadObject(ObjectInputStreamin)throwsIOException

{ id=in.readInt(); …}}定制對象的串行化:在類定義中重寫readObject()和WriteObject()方法。字節(jié)流 ——對象流串行化只能保存對象的非靜態(tài)成員變量,而不能保存任何成員方法和靜態(tài)成員變量,并且保存的只是變量的值,對于變量的任何修飾符都不能保存。對于某些類型的對象,其狀態(tài)是瞬時的,這樣的對象是無法保存其狀態(tài)的,如Thread對象或流對象。對于這樣的成員變量,必須用transient關鍵字標明,否則編譯器將報錯。任何用transient關鍵字標明的成員變量,都不會被保存。另外,串行化可能涉及將對象存放到磁盤上或在網絡上發(fā)送數據,這時會產生安全問題。對于一些需要保密的數據,不應保存在永久介質中(或者不應簡單地不加處理地保存下來),為了保證安全,應在這些變量前加上transient關鍵字。字節(jié)流 ——管道流管道用來把一個程序、線程和代碼塊的輸出連接到另一個程序、線程和代碼塊的輸入。java.io中提供了類PipedInputStream和PipedOutputStream作為管道的輸入/輸出流。管道輸入流作為一個通信管道的接收端,管道輸出流則作為發(fā)送端。管道流必須是輸入輸出并用,即在使用管道前,兩者必須進行連接。輸出流輸入流字節(jié)流 ——管道流管道輸入/輸出流可以用兩種方式進行連接:1)在構造方法中進行連接PipedInputStream(PipedOutputStreampos);PipedOutputStream(PipedInputStream

pis);2)通過各自的connect()方法連接在類PipedInputStream中,connect(PipedOutputStreampos);在類PipedOutputStream中,connect(PipedInputStream

pis);classpipedstream{publicstaticvoidmain(Stringargs[])throwsIOException

{

byteaByteData1=123,aByteData2=111;PipedInputStreampis=newPipedInputStream();

PipedOutputStreampos=newPipedOutputStream(pis);System.out.println("PipedInputStream");try{pos.write(aByteData);pos.write(aByteData2);System.out.println((byte)pis.read());System.out.println((byte)pis.read());}

finally

{

pis.close(); pos.close();}}}將數據從輸出管道進,從輸入管道出字節(jié)流 ——內存讀寫流為了支持內存的讀/寫,java.io中提供了類ByteArrayInputStream、ByteArrayOutputStream和StringBufferInputStream。

ByteArrayInputStream可以從指定的字節(jié)數組中讀取數據。

ByteArrayOutputStream中提供了緩沖區(qū)可以存放數據(緩沖區(qū)大小可以在構造方法中設定,缺省為32),可以用write()方法向其中寫入數據,然后用toByteArray()方法將緩沖區(qū)中的有效字節(jié)寫到字節(jié)數組中去。

StringBufferInputStream與ByteArrayInputStream相類似,不同點在于它是從字符緩沖區(qū)StringBuffer中讀取16位的Unicode數據,而不是8位的字節(jié)數據。字節(jié)流 ——順序輸入流

java.io中提供了類SequenceInputStream,使應用程序可以將幾個輸入流順序連接起來,讓程序員看起來就像是一個比較長的流一樣。順序輸入流提供了將多個不同的輸入流統(tǒng)一為一個輸入流的功能,這使得程序可能變得更加簡潔。如:FileInputStreamf1,f2;Strings;f1=newFileInputStream(“file1.txt”);f2=newFileInputStream(“file2.txt”);SequenceInputStreamfs=newSequenceInputStream(f1,f2);DataInputStreamds=newDataInputStream(fs);while((s=ds.readLine())!=null)System.out.println(s);字符流前面說過,在JDK1.1之前,java.io包中的流只有普通的字節(jié)流(以byte為基本處理單位的流),這種流對于以16位的Unicode碼表示的字符流處理很不方便。從JDK1.1開始,java.io包中加入了專門用于字符流處理的類,它們是以Reader和Writer為基礎派生的一系列類。同類InputStream和OutputStream一樣,Reader和Writer也是抽象類,只提供了一系列用于字符流處理的接口。它們的方法與類InputStream和OutputStream類似,只不過其中的參數換成字符或字符數組。

字節(jié)流中類DatainputStream的readLine方法,可以以字節(jié)形式讀入,以Unicode形式輸出(StringreadLine())。byteUnicode16bit8bit+00000000字符流

——InputStreamReader和OutputStreamWriter

InputStreamReader和OutputStreamWriter是java.io包中用于處理字符流的最基本的類,用來在字節(jié)流和字符流之間作為中介。使用這兩者進行字符處理時,在構造方法中應指定一定的平臺規(guī)范,以便把以字節(jié)方式表示的流轉換為特定平臺上的字符表示。

InputStreamReader(InputStreamin);//缺省規(guī)范

InputStreamReader(InputStreamin,Stringenc);//指定規(guī)范enc

OutputStreamWriter(OutputStreamout);//缺省規(guī)范

OutputStreamWriter(OutputStreamout,Stringenc);//指定規(guī)范enc

如果讀取的字符流不是來自本地時(比如網上某處與本地編碼方式不同的機器),那么在構造字符輸入流時就不能簡單地使用缺省編碼規(guī)范,而應該指定一種統(tǒng)一的編碼規(guī)范“ISO8859_1”,這是一種映射到ASCII碼的編碼方式,能夠在不同平臺之間正確轉換字符。InputStreamReaderir=newInputStreamReader(is,“8859_1”);字符流

——BufferedReader和BufferedWriter同樣的,為了提高字符流處理的效率,java.io中也提供了緩沖流BufferedReader和BufferedWriter。其構造方法與BufferedInputStream和BufferedOutputStream相類似。另外,除了read()和write()方法外,它還提供了

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論