Java面向?qū)ο蟪绦蛟O(shè)計(IDEA版) 課件 第11、12章 輸入輸出、圖形界面編程_第1頁
Java面向?qū)ο蟪绦蛟O(shè)計(IDEA版) 課件 第11、12章 輸入輸出、圖形界面編程_第2頁
Java面向?qū)ο蟪绦蛟O(shè)計(IDEA版) 課件 第11、12章 輸入輸出、圖形界面編程_第3頁
Java面向?qū)ο蟪绦蛟O(shè)計(IDEA版) 課件 第11、12章 輸入輸出、圖形界面編程_第4頁
Java面向?qū)ο蟪绦蛟O(shè)計(IDEA版) 課件 第11、12章 輸入輸出、圖形界面編程_第5頁
已閱讀5頁,還剩148頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

面向?qū)ο蟪绦蛟O(shè)計第11章輸入/輸出

1I/O概述23主要內(nèi)容面向?qū)ο蟪绦蛟O(shè)計(Java語言描述微課版基于IntelliJIDEA)二進(jìn)制I/O流案例:文件加密解密45文本I/O流案例:統(tǒng)計文件行數(shù)、單詞數(shù)和字符數(shù)6對象序列化11.1I/O概述面向?qū)ο蟪绦蛟O(shè)計輸入/輸出(I/O)是任何程序設(shè)計語言都提供的功能,Java語言從一開始就支持I/O,最初是通過java.io包中的類和接口提供支持的,之后又出現(xiàn)了NIO和NIO.2。概述目前Java支持流式I/O和文件I/O。流式I/O分為輸入流和輸出流。程序為了獲得外部數(shù)據(jù),可以在數(shù)據(jù)源(文件、內(nèi)存及網(wǎng)絡(luò)套接字)上創(chuàng)建一個輸入流,然后用read()方法順序讀取數(shù)據(jù)。類似地,程序可以在輸出設(shè)備上創(chuàng)建一個輸出流,然后用write()方法將數(shù)據(jù)寫到輸出流。所有的數(shù)據(jù)流都是單向的。使用輸入流只能從中讀取數(shù)據(jù);使用輸出流,只能向其寫出數(shù)據(jù),如圖13-1所示。概述按照處理數(shù)據(jù)的類型分,數(shù)據(jù)流又可分為二進(jìn)制流和文本流,也分別稱為字節(jié)流和字符流,它們處理的信息的基本單位分別是字節(jié)和字符。java.io.File類用來表示物理磁盤上的實際文件或目錄,但它不表示文件中數(shù)據(jù)。11.1.1File類應(yīng)用絕對文件名是由驅(qū)動器字母、完整的路徑以及文件名組成,如D:\study\Hello.txt是Windows系統(tǒng)下的一個絕對文件名。相對文件名是相對于當(dāng)前工作目錄的。例如,Hello.txt是一個相對文件名。如果當(dāng)前工作目錄是D:\study,絕對文件名是D:\study\Hello.txt。importjava.io.*;publicclassFileDemo{publicstaticvoidmain(String[]args){varfile=newFile("Hello.txt");//此時文件還不存在!}}編譯并運行該程序,當(dāng)查看當(dāng)前目錄,找不能到Hello.txt文件。這說明創(chuàng)建一個File實例并不是創(chuàng)建實際的文件,而僅僅創(chuàng)建一個表示文件的對象。如果要創(chuàng)建實際的文件,可使用下面代碼:try{booleansuccess=false;varfile=newFile("Hello.txt");System.out.println(file.exists());//輸出文件是否存在success=file.createNewFile();

//創(chuàng)建文件是否成功System.out.println(success);System.out.println(file.exists());//輸出文件是否存在}catch(IOExceptione){System.out.println(e.toString());}下面是File類最常用操作方法。publicbooleanexists():測試File對象是否存在。publiclonglength():返回指定文件的字節(jié)長度,文件不存在時返回0。publicbooleancreateNewFile():當(dāng)文件不存在時,創(chuàng)建一個空文件時返回true,否則返回false。publicbooleanrenameTo(FilenewName):重新命名指定的文件對象,正常重命名時返回true,否則返回false。publicbooleandelete():刪除指定的文件。若為目錄,當(dāng)目錄為空才能刪除。publiclonglastModified():返回文件最后被修改的日期和時間,它計算的是從1970年1月1日0時0分0秒開始的毫秒數(shù)。11.1.1File類應(yīng)用文件通??梢苑譃槲谋疚募投M(jìn)制文件。文本文件(textfile)是包含字符序列的文件,可以使用文本編輯器查看或通過程序閱讀。內(nèi)容必須按二進(jìn)制序列處理的文件稱為二進(jìn)制文件(binaryfile)。11.1.2文本I/O與二進(jìn)制I/O實際上,計算機并不區(qū)分二進(jìn)制文件與文本文件。所有的文件都是以二進(jìn)制形式來存儲的,因此,從本質(zhì)上說,所有的文件都是二進(jìn)制文件。對于文本I/O而言,在寫入一個字符時,Java虛擬機會將字符的統(tǒng)一碼轉(zhuǎn)換為文件指定的編碼,在讀取字符時,將文件指定的編碼轉(zhuǎn)換為統(tǒng)一碼。11.1.2文本I/O與二進(jìn)制I/O使用文本I/O將字符串“123”寫入文件,那么每個字符的二進(jìn)制編碼都會寫入到文件。二進(jìn)制I/O不需要進(jìn)行轉(zhuǎn)換。如果使用二進(jìn)制I/O向文件寫入一個數(shù)據(jù),就是將內(nèi)存中的值復(fù)制到文件中。11.1.2文本I/O與二進(jìn)制I/O例如,一個byte類型的數(shù)值123在內(nèi)存中表示為01111011,將它寫入文件也是01111011。使用二進(jìn)制I/O讀取一個字節(jié)時,就會從輸入流中讀取一個字節(jié)的二進(jìn)制編碼。11.2二進(jìn)制I/O流面向?qū)ο蟪绦蛟O(shè)計6.1.1publicintread()publicintread(byte[]b)publicvoidclose()InputStream類是二進(jìn)制輸入流的根類,它有多個子類。InputStream類和OutputStream類面向?qū)ο蟪绦蛟O(shè)計(Java語言描述微課版基于IntelliJIDEA)6.1.1

publicvoidwrite(intb)publicvoidwrite(byte[]b)publicvoidclose()OutputStream類是二進(jìn)制輸出流的根類,它有多個子類。面向?qū)ο蟪绦蛟O(shè)計(Java語言描述微課版基于IntelliJIDEA)InputStream類和OutputStream類FileInputStream類和FileOutputStream類用來實現(xiàn)文件的輸入輸出處理。11.2.2FileOutputStream類和FileInputStream類FileInputStream類和FileOutputStream類都實現(xiàn)了java.lang.AutoClosable接口,因此可以在try-with-resources語句中使用,當(dāng)流使用完自動將它們關(guān)閉。FileOutputStream類的常用構(gòu)造方法如下:FileOutputStream(Stringname):用表示文件的字符串創(chuàng)建文件輸出流對象。FileOutputStream(Stringname,booleanappend):用表示文件的字符串創(chuàng)建文件輸出流對象。如果append參數(shù)為true,則指明打開的文件輸出流不覆蓋原來的內(nèi)容,而是從文件末尾寫入新內(nèi)容,否則覆蓋原來的文件內(nèi)容。FileOutputStream(Filefile):用File對象創(chuàng)建文件輸出流對象。11.2.2FileOutputStream類和FileInputStream類FileInputStream類的兩個常用的構(gòu)造方法如下:

FileInputStream(Stringname):用表示文件的字符串創(chuàng)建文件輸入流對象。FileInputStream(Filefile):用File對象創(chuàng)建文件輸入流對象。11.2.2FileOutputStream類和FileInputStream類若指定的文件不存在,則產(chǎn)生FileNotFoundException異常,它是檢查異常,必須捕獲或聲明拋出。也可以先創(chuàng)建File對象,然后測試該文件是否存在,若存在再創(chuàng)建文件輸入流。publicstaticvoidmain(String[]args){varoutputFile=newFile("output.dat");try(varout=newFileOutputStream(outputFile);){for(vari=0;i<10;i++){intx=(int)(Math.random()*90)+10;out.write(x);}out.flush();//刷新輸出流System.out.println("已向文件寫入10個兩位數(shù)!");}catch(IOExceptione){System.out.println(e.toString());}}程序11.1WriteByteDemo.java

publicstaticvoidmain(String[]args){

varinputFile=newFile("output.dat");

try(

varin=newFileInputStream(inputFile);){

intc=in.read();

while(c!=-1){System.out.print(c+"");c=in.read();

}}catch(IOExceptione){System.out.println(e.toString());}

}程序11.2ReadByteDemo.javaBufferedInputStream的構(gòu)造方法如下:BufferedInputStream(InputStreamin):使用參數(shù)in指定的輸入流對象創(chuàng)建一個緩沖輸入流。

BufferedInputStream(InputStreamin,intsize):使用參數(shù)in指定的輸入流對象創(chuàng)建一個緩沖輸入流,并且通過size參數(shù)指定緩沖區(qū)大小,默認(rèn)為512個字節(jié)。使用上面兩個類,可以把輸入輸出流包裝成具有緩沖功能的流,從而提高輸入輸出的效率。11.2.3BufferedOutputStream類和BufferedInputStream類BufferedOutputStream為緩沖輸出流,BufferedInputStream為緩沖輸入流,這兩個類用來對流實現(xiàn)緩沖功能。使用緩沖流可以減少讀寫數(shù)據(jù)的次數(shù),加快輸入輸出的速度。11.2.3BufferedOutputStream類和BufferedInputStream類BufferedOutputStream類的構(gòu)造方法如下:BufferedOutputStream(OutputStreamout):使用參數(shù)out指定的輸出流對象創(chuàng)建一個緩沖輸出流。BufferedOutputStream(OutputStreamout,intsize):使用參數(shù)out指定的輸出流對象創(chuàng)建一個緩沖輸出流,并且通過size參數(shù)指定緩沖區(qū)大小,默認(rèn)為512個字節(jié)。DataOutputStream類和DataInputStream類分別是數(shù)據(jù)輸出流和數(shù)據(jù)輸入流。使用這兩個類可以實現(xiàn)基本數(shù)據(jù)類型的輸入輸出。這兩個類的構(gòu)造方法如下:11.2.4DataOutputStream類和DataInputStream類DataOutputStream(OutputStreamoutstream):參數(shù)outstream是字節(jié)輸出流對象。DataInputStream(InputStreaminstream):參數(shù)instream是字節(jié)輸入流對象。varinFile=newDataInputStream(newBufferedInputStream(newFileInputStream("input.dat")));varoutFile=newDataOutputStream(newBufferedOutputStream(newFileOutputStream("output.dat")));11.2.4DataOutputStream類和DataInputStream類DataOutputStream類定義的常用方法如下所示。publicvoidwriteByte(intv):將整數(shù)v低的8位寫入輸出流,忽略高24位。publicvoidwriteInt(intv):向輸出流寫一個4個字節(jié)的整數(shù)。publicvoidwriteLong(longv):向輸出流寫一個8個字節(jié)的長整數(shù)。publicvoidwriteDouble(doublev):向輸出流寫一8個字節(jié)的double型浮點數(shù)。publicvoidwriteBytes(Strings):將參數(shù)字符串每個字符的低位字節(jié)按順序?qū)懙捷敵隽髦?。publicvoidwriteUTF(Strings):將參數(shù)字符串字符按UTF-8的格式寫出到輸出流中。UTF-8格式的字符串中每個字符可能是1個、2個或3個字節(jié),另外字符串前要加2個字節(jié)存儲字符數(shù)量。11.2.4DataOutputStream類和DataInputStream類DataInputStream類定義的常用方法如下所示。publicbytereadByte():從輸入流讀一個字節(jié)并返回該字節(jié)。publicintreadInt():從輸入流讀4個字節(jié),返回一個int型值。publiclongreadLong():從輸入流讀8個字節(jié),返回一個long型值。publicdoublereadDouble():從輸入流讀8個字節(jié),返回一個double型值。publicStringreadLine():從輸入流讀下一行文本。該方法已被標(biāo)記為不推薦使用。publicStringreadUTF():從輸入流讀UTF-8格式的字符串。編寫程序,使用DataOutputStream流將數(shù)據(jù)寫入到文件中,這里還將數(shù)據(jù)流包裝成緩沖流。之后,使用DataInputStream流從文件中讀取數(shù)據(jù)并在控制臺輸出。數(shù)據(jù)I/O流的應(yīng)用

//向文件中寫數(shù)據(jù)

try(FileOutputStreamoutput=newFileOutputStream("data.dat");DataOutputStreamdataOutStream=newDataOutputStream(

newBufferedOutputStream(output));

){dataOutStream.writeDouble(123.456);dataOutStream.writeInt(100);dataOutStream.writeUTF("Java語言");}catch(IOExceptione){e.printStackTrace();

}程序11.3DataStreamDemo.java

//從文件中讀取數(shù)據(jù)

try(FileInputStreaminput=newFileInputStream("data.dat");DataInputStreamdataInStream=newDataInputStream(

newBufferedInputStream(input));

){while(dataInStream.available()>0){

doubled=dataInStream.readDouble();

inti=dataInStream.readInt();Strings=dataInStream.readUTF();System.out.println("d="+d);System.out.println("i="+i);System.out.println("s="+s);

}}catch(IOExceptione){e.printStackTrace();

}PrintStream類為打印各種類型的數(shù)據(jù)提供了方便。PrintStream類定義了多個print()和println()方法,可以打印輸出各種類型的數(shù)據(jù),這些方法都是把數(shù)據(jù)轉(zhuǎn)換成字符串,然后輸出。如果輸出到文件中則可以用記事本瀏覽。println()方法輸出后換行,print()方法輸出后不換行。11.2.5PrintStream類當(dāng)把對象傳遞給這兩個方法時則先調(diào)用對象的toString()方法將對象轉(zhuǎn)換為字符串形式,然后輸出。在前面章節(jié)大量使用的System.out對象就是PrintStream類的一個實例,用于向控制臺輸出數(shù)據(jù)。Java在System類中定義了標(biāo)準(zhǔn)輸出流out,標(biāo)準(zhǔn)輸入流in以及標(biāo)準(zhǔn)錯誤輸出流err,如下所示。11.2.6標(biāo)準(zhǔn)輸入輸出流publicstaticfinaljava.io.PrintStreamout;publicstaticfinaljava.io.InputStreamin;publicstaticfinaljava.io.PrintStreamerr;System.in是InputStream類的實例??梢允褂胷ead()方法從鍵盤上讀取字節(jié),也可以將它包裝成數(shù)據(jù)流讀取各種類型的數(shù)據(jù)和字符串。System.out和System.err是PrintStream類的實例,可以使用該類定義的方法輸出各種類型數(shù)據(jù)。6.1.1問題描述編寫程序,隨機生成10個1000到2000之間的整數(shù),將它們寫到一個文件data.dat中,然后從該文件中讀出這些整數(shù),要求使用DataInputStream和DataOutputStream類實現(xiàn)。課堂討論與訓(xùn)練面向?qū)ο蟪绦蛟O(shè)計(Java語言描述微課版基于IntelliJIDEA)11.3案例:文件加密解密面向?qū)ο蟪绦蛟O(shè)計編寫一個簡單的文件加密、解密程序。文件加密、解密有多種方法,本案例使用一種簡單的算法,對文件的內(nèi)容使用“異或”運算進(jìn)行加密后保存到指定的文件中。要對文件解密,讀取文件中的加密內(nèi)容,再次使用“異或”運算解密得到原文件內(nèi)容。文件加密解密本案例使用“異或”運算對文件中字節(jié)進(jìn)行加密、解密的原理可以描述如下:按位“異或”運算符的運算規(guī)則是:兩個操作數(shù)中,如果相應(yīng)位相同,則結(jié)果為0,否則為1,例如:00101010^00010111=00111101“異或”運算符的特點是:用同一個數(shù)b對操作數(shù)a進(jìn)行兩次“異或”運算,結(jié)果仍然為原值a。就是,如果c=a^b,那么a=c^b,即用同一個數(shù)b對數(shù)a進(jìn)行兩次“異或”運算的結(jié)果又是數(shù)a。利用“異或”運算的這個性質(zhì),可以實現(xiàn)簡單的字節(jié)加密、解密操作。文件加密解密(1)程序首先要求用戶輸入要加密的文件名、加密后的文件名以及加密使用的秘鑰,也就是要在讀取的字節(jié)上做“異或”運算的整數(shù)。(2)使用FileInputStream和FileOutputStream創(chuàng)建輸入流(源文件)和輸出流(加密文件),從源文件讀取每個字節(jié)然后對它做“異或”運算,將結(jié)果寫入加密的文件。文件加密解密(3)文件解密的過程與加密的過程類似。使用FileInputStream和FileOutputStream創(chuàng)建輸入流(要解密的文件)和輸出流(解密后文件),從輸入流讀取每個字節(jié)然后對它做“異或”運算,將結(jié)果寫入解密后的文件。這里要注意,解密使用的秘鑰需與加密使用的秘鑰相同,否則得不到源文件。varinput=newScanner(System.in);StringsourceFile=null;StringsecretFile=null;varkeyValue=0;System.out.print("請輸入源文件名:");sourceFile=input.nextLine();System.out.print("請輸入加密文件名:");secretFile=input.nextLine();System.out.print("請輸入秘鑰:");keyValue=input.nextInt();程序11.4FileEncription.javavarsrcFile=newFile(sourceFile);varencFile=newFile(secretFile);if(!srcFile.exists()){System.out.println("源文件不存在!");System.exit(0);}if(!encFile.exists()){System.out.println("創(chuàng)建加密文件!");encFile.createNewFile();}try(varfis=newFileInputStream(srcFile);varfos=newFileOutputStream(encFile); ){vardataOfFile=fis.read();while(dataOfFile!=-1){

dataOfFile=dataOfFile^keyValue;fos.write(dataOfFile);dataOfFile=fis.read();}}

varinput=newScanner(System.in);StringsecretFile=null;StringresultFile=null;

varkeyValue=0;System.out.print("請輸入要解密文件:");secretFile=input.nextLine();System.out.print("請輸入解密后文件名:");resultFile=input.nextLine();System.out.print("請輸入秘鑰:");keyValue=input.nextInt();程序11.5FileDecription.java

varencFile=newFile(secretFile);

vardecFile=newFile(resultFile);

if(!encFile.exists()){System.out.println("解密的文件不存在!");System.exit(0);

}

if(!decFile.exists()){//System.out.println("創(chuàng)建目標(biāo)文件!");decFile.createNewFile();

}

try(

varfis=newFileInputStream(encFile);

varfos=newFileOutputStream(decFile);

){

vardataOfFile=fis.read();

while(dataOfFile!=-1){dataOfFile=dataOfFile^keyValue;fos.write(dataOfFile);dataOfFile=fis.read();

}

}11.4文本I/O流面向?qū)ο蟪绦蛟O(shè)計文本I/O流以字符為基本單位,也叫字符I/O流。抽象類Reader和Writer分別是文本輸入流和輸出流的根類。概述概述Writer類是字符輸出流的根類,定義的常用方法有:publicvoidwrite(intc):向輸出流中寫一個字符,實際是將int型的c的低16位寫入輸出流。publicvoidwrite(Stringstr):把字符串str寫入輸出流中。publicvoidclose():關(guān)閉輸出流。11.4.1Reader類和Writer類Reader類是文本輸入流的根類,定義的常用方法有:

publicintread():讀取一個字符,返回范圍為0到65535之間int型值,如果到達(dá)流的末尾返回-1。publicvoidclose():關(guān)閉輸入流。FileReader類構(gòu)造方法有:FileReader(StringfileName)FileReader(Filefile)11.4.2FileWriter類和FileReader類FileWriter類構(gòu)造方法有:

FileWriter(StringfileName)

FileWriter(Filefile)FileWriter(StringfileName,booleanappend)下面的FileCopyDemo.java程序使用FileReader和FileWriter將文件input.txt(在項目跟目錄下)的內(nèi)容復(fù)制到output.txt文件中。11.4.2FileWriter類和FileReader類FileinputFile=newFile("input.txt");FileoutputFile=newFile("output.txt");try(FileReaderin=newFileReader(inputFile);FileWriterout=newFileWriter(outputFile);

){intc=in.read();while(c!=-1){out.write(c);c=in.read();

}}catch(IOExceptione){System.out.println(e.toString());

}程序11.4FileCopyDemo.javaBufferedReader類和BufferedWriter類分別實現(xiàn)具有緩沖功能的字符輸入輸出流。這兩個類用來將其他的字符流包裝成緩沖字符流,以提高讀寫數(shù)據(jù)的效率。BufferedReader類的構(gòu)造方法如下:publicBufferedReader(Readerin):用默認(rèn)的緩沖區(qū)大小創(chuàng)建緩沖字符輸入流。publicBufferedReader(Readerin,intsz):用指定的緩沖區(qū)大小創(chuàng)建緩沖字符輸入流。11.4.3BufferedReader類和BufferedWriter類下面代碼創(chuàng)建了一個BufferedReader對象:

varin=newBufferedReader(newFileReader("input.txt"));BufferedWriter類的構(gòu)造方法如下:BufferedWriter(Writerout):用默認(rèn)的緩沖區(qū)大小創(chuàng)建緩沖字符輸出流。BufferedWriter(Writerout,intsz):用指定的緩沖區(qū)大小創(chuàng)建緩沖字符輸出流。11.4.3BufferedReader類和BufferedWriter類通常Writer直接將輸出發(fā)送到基本的字符或字節(jié)流,建議在Writer上(如FileWriter和OutputStreamWriter)包裝BufferedWriter,例如:

var

br=newBufferedWriter(newFileWriter("output.txt"));StringfileName="article.txt";

intsum=0;

try(FileReaderinFile=newFileReader(fileName);BufferedReaderreader=newBufferedReader(inFile);

){StringaLine=reader.readLine();

while(aLine!=null){String[]words=aLine.split("[,.]");sum=sum+words.length;aLine=reader.readLine();

}}catch(IOExceptione){System.out.println(e.toString());

}System.out.println("單詞數(shù)量為:"

+sum);程序11.5WordsCount.javaPrintWriter類實現(xiàn)字符打印輸出流,它的構(gòu)造方法如下:PrintWriter(Writerout):使用參數(shù)指定的輸出流對象out創(chuàng)建一個打印輸出流。PrintWriter(Writerout,booleanautoFlush):如果autoFlush指定為true,則在輸出之前自動刷新輸出流。11.4.4PrintWriter類PrintWriter類定義的常用方法如下。publicvoidprintln(booleanb):輸出一個boolean型數(shù)據(jù)。publicvoidprintln(Strings):輸出一個String型數(shù)據(jù)。publicvoidprintln(Objectobj):將obj轉(zhuǎn)換成String型數(shù)據(jù),然后輸出。下面程序隨機產(chǎn)生10個100到200之間的整數(shù),然后使用PrintWriter對象輸出到文件number.txt中。11.4.4PrintWriter類for(var

i=0;i<10;i++){

var

num=(int)(Math.random()*101)+100;

pw.println(num);}varfileName="number.txt"; varout=newFileWriter(newFile(fileName));varpw=newPrintWriter(out,true);//向文件中隨機寫入10個隨機整數(shù)for(vari=0;i<10;i++){varnum=(int)(Math.random()*101)+100;pw.println(num);}pw.close();程序11.6PrintWriterDemo.java//從文件中讀出10個整數(shù)varin=newFileReader(newFile(fileName));varreader=newBufferedReader(in);varaLine=reader.readLine();while(aLine!=null){System.out.print(aLine+"");aLine=reader.readLine();}reader.close();該程序運行后在項目目錄下創(chuàng)建一個number.txt文本文件,并且寫入10個整數(shù),該文件可以用記事本打開。使用Scanner類從鍵盤讀取數(shù)據(jù),這是在創(chuàng)建Scanner對象時將標(biāo)準(zhǔn)輸入設(shè)備System.in作為其構(gòu)造方法的參數(shù)。使用Scanner還可以關(guān)聯(lián)文本文件,從文本文件中讀取數(shù)據(jù)。11.4.5使用Scanner對象Scanner類的常用的構(gòu)造方法有:publicScanner(Stringsource):用指定的字符串構(gòu)造Scanner對象,以便從中讀取數(shù)據(jù)。publicScanner(InputStreamsource):用指定的輸入流構(gòu)造一個Scanner對象,以便從中讀取數(shù)據(jù)。Scanner類的常用方法如下所示:publicbytenextByte():讀取下一個標(biāo)記并將其解析成byte型數(shù)。publicintnextInt():讀取下一個標(biāo)記并將其解析成int型數(shù)。publicdoublenextDouble():讀取下一個標(biāo)記并將其解析成double型數(shù)。publicStringnext():讀取下一個標(biāo)記并將其解析成字符串。publicStringnextLine():讀取當(dāng)前行作為一個String型字符串。11.4.5使用Scanner對象varfile=newFile("number.txt");try(varinput=newFileInputStream(file);varsc=newScanner(input)){while(sc.hasNextInt()){ vartoken=sc.nextInt(); System.out.println(token);}}catch(IOExceptione){e.printStackTrace();} 程序11.7TextFileDemo.java11.5案例:統(tǒng)計文件行數(shù)、單詞數(shù)和字符數(shù)面向?qū)ο蟪绦蛟O(shè)計經(jīng)常需要對文本文件分析,比如查找有關(guān)內(nèi)容,進(jìn)行某種統(tǒng)計等。本案例要求編寫程序,統(tǒng)計一個英文文本文件中的字符數(shù)、單詞數(shù)和行數(shù)。單詞由空格和逗號、句號、分號和感嘆號這幾個個標(biāo)點符號分隔,文件名由鍵盤讀入。統(tǒng)計文件行數(shù)、單詞數(shù)和字符數(shù)(1)創(chuàng)建Scanner對象,從鍵盤讀取要統(tǒng)計的源文件名,并判斷文件是否存在,存在繼續(xù),不存在則強制程序結(jié)束。(2)創(chuàng)建FileReader和BufferedReader對象,使用readLine()方法從指定的文件讀取字符串進(jìn)行解析。(3)對每一行的字符串,用String的length()方法計算字符數(shù),再使用String類的split()方法根據(jù)置分隔符來解析所包含的單詞數(shù)。

varinput=newScanner(System.in);

varfilename="";System.out.print("請輸入文本文件名:");filename=input.nextLine();

varfile=newFile(filename);

if(!file.exists()){System.out.println("您輸入的文件不存在!");System.exit(0);

}程序11.8WordsCount.java

try(

varfis=newBufferedReader(newFileReader(file));

){

varcharNums=0;

varwordsNums=0;

varlineNums=0;

varaLine=fis.readLine();

while(aLine!=null){charNums=charNums+aLine.length();

varwords=aLine.split("[,;.!]");//5個符號wordsNums=wordsNums+words.length;lineNums=lineNums+1;aLine=fis.readLine();

}

System.out.println("文件="

+filename);System.out.println("共有行數(shù)="

+lineNums+"行");System.out.println("單詞數(shù)="

+wordsNums+"個"

);System.out.println("總共字符數(shù)="

+charNums+"個");}catch(IOExceptionioe){ioe.printStackTrace();

}11.6對象序列化面向?qū)ο蟪绦蛟O(shè)計對象的壽命通常隨著創(chuàng)建該對象的程序的終止而終止。有時可能需要將對象的狀態(tài)保存下來,在需要時再將其恢復(fù)。對象狀態(tài)的保存和恢復(fù)可以通過對象I/O流實現(xiàn)。11.6.1對象序列化與對象流將程序中的對象輸出到外部設(shè)備(如磁盤、網(wǎng)絡(luò))中,稱為對象序列化(serialization)。反之,從外部設(shè)備將對象讀入程序中稱為對象反序列化(deserialization)。一個類的對象要實現(xiàn)對象序列化,必須實現(xiàn)java.io.Serializable接口,該接口的定義如下。publicinterfaceSerializable{}Serializable只是標(biāo)識性接口,其中沒有定義任何方法。11.6.1對象序列化與對象流一個類的對象要序列化,除了必須實現(xiàn)Serializable接口外,還需創(chuàng)建對象輸出流和對象輸入流,然后,通過對象輸出流將對象狀態(tài)保存下來,通過對象輸入流恢復(fù)對象的狀態(tài)。在java.io包中定義了ObjectInputStream和ObjectOutputStream類,分別稱為對象輸入流和對象輸出流。若將對象寫到外部設(shè)備需要建立ObjectOutputStream類的對象,構(gòu)造方法為:publicObjectOutputStream(OutputStreamout)參數(shù)out為一個字節(jié)輸出流對象。11.6.2向ObjectOutputStream中寫入對象創(chuàng)建了對象輸出流后,就可以調(diào)用它的writeObject()方法將一個對象寫到流中,該方法格式為:publicfinalvoidwriteObject(Objectobj)throwsIOException若寫出的對象不是可序列化的,該方法會拋出NotSerializableException異常。由于ObjectOutputStream類實現(xiàn)了DataOutput接口,該接口中定義多個方法用來寫入基本數(shù)據(jù)類型,如writeInt()、writeFloat()及writeDouble()等,可以使用這些方法向?qū)ο筝敵隽髦袑懟緮?shù)據(jù)類型。11.6.2向ObjectOutputStream中寫入對象下面代碼將一些數(shù)據(jù)和對象寫到對象輸出流中。

oos.writeInt(2022);

oos.writeObject("你好");

oos.writeObject(LocalDate.now());若要從外部設(shè)備上讀取對象,需建立ObjectInputStream對象,該類的構(gòu)造方法為:publicObjectInputStream(InputStreamin)參數(shù)in為字節(jié)輸入流對象。11.6.3從ObjectInputStream中讀取對象通過調(diào)用ObjectInputStream類的方法readObject()方法可以讀取一個對象,該方法的聲明格式為:publicfinalObjectreadObject()throwsIOException在使用readObject()方法讀出對象時,其類型和順序必須與寫入時一致。ObjectInputStream類實現(xiàn)了DataInput接口,該接口中定義了讀取基本數(shù)據(jù)類型的方法,如readInt()、readFloat()及readDouble(),使用這些方法可以從ObjectInputStream流中讀取基本數(shù)據(jù)類型。11.6.3從ObjectInputStream中讀取對象下面代碼在InputStream對象上建立一個對象輸入流對象。

var

fis=newFileInputStream("data.ser");

var

oip=newObjectInputStream(fis);

int

i=ois.readInt();

vartoday=(String)ois.readObject();

vardate=(LocalDate)ois.readObject();下面的例子說明如何實現(xiàn)對象的序列化和反序列化,這里的對象是Customer記錄類型的對象,它實現(xiàn)了Serializable接口。關(guān)于記錄類型,請參閱11.1節(jié)。示例:對象序列化和反序列化程序11.8Customer.javapackagecom.boda.xy;importjava.io.Serializable;publicrecordCustomer(intid,Stringname,Stringaddress)implementsSerializable{}varcustomer=newCustomer(101,"劉明","北京市海淀區(qū)");vartoday=LocalDate.now();//序列化try(varoutput=newFileOutputStream("D:\\study\\customer.dat"); varoos=newObjectOutputStream(output)){ oos.writeObject(customer);//寫入一個客戶對象 oos.writeObject(today);//寫入一個日期對象}catch(IOExceptione){ e.printStackTrace();}程序11.9ObjectSerializeDemo.javatry(varinput=newFileInputStream("D:\\study\\customer.dat");varois=newObjectInputStream(input)){while(true){ try{ customer=(Customer)ois.readObject(); System.out.println("客戶號:"+customer.id()); System.out.println("姓名:"+()); System.out.println("地址:"+customer.address());today=(LocalDate)ois.readObject(); System.out.println("日期:"+today); }catch(EOFExceptione){}如果數(shù)組中的所有元素都是可序列化的,這個數(shù)組就是可序列化的。一個完整的數(shù)組可以用writeObject()方法存入文件,之后用readObject()方法讀取到程序中。11.6.4序列化數(shù)組下面程序?qū)⒁粋€有5個元素的int型數(shù)組和一個有3個元素的String型數(shù)組存儲到文件中,然后將它們從文件中讀取出顯示在控制臺上。try{int[]numbers={1,2,3,4,5};String[]cities={"北京","上海","廣州"};//序列化try(varoutput=newFileOutputStream("array.dat",true);varoos=newObjectOutputStream(output);){ oos.writeObject(numbers);//將numbers數(shù)組寫入文件 oos.writeObject(cities);//將cities數(shù)組寫入文件}catch(IOExceptione){e.printStackTrace(); }程序11.10ArraySerialDemo.javatry(//反序列化varinput=newFileInputStream("array.dat");varois=newObjectInputStream(input);){//讀取數(shù)組對象int[]newNumbers=(int[])ois.readObject();String[]newStrings=(String[])ois.readObject();for(intn:newNumbers) System.out.print(n+"");System.out.println();for(Strings:newStrings) System.out.print(s+"");本章知識點導(dǎo)圖面向?qū)ο蟪绦蛟O(shè)計第12章圖形界面編程

1組件和容器23主要內(nèi)容面向?qū)ο蟪绦蛟O(shè)計(Java語言描述微課版第基于IntelliJIDEA)容器布局事件處理45常用組件案例學(xué)習(xí):八皇后問題解6案例學(xué)習(xí):簡單的日歷程序面向?qū)ο蟪绦蛟O(shè)計12.1組件和容器Java從1.0版就提供了一個AWT類庫,稱為抽象窗口工具箱(AbstractWindowToolkit,AWT)。使用AWT創(chuàng)建GUI存在嚴(yán)重缺陷。概述Java從1.2版開始提供了一個新的組件庫Swing,該庫可以說是第二代GUI開發(fā)工具集。Swing組件完全用Java編寫,它們不依賴于特定平臺,因此是輕量級的組件(lightweightcomponent),輕量級組件具有重要優(yōu)點,包括高效性和靈活性。12.1.1Swing概述由于Swing組件比AWT組件有許多優(yōu)點,所以新開發(fā)的程序應(yīng)該使用Swing組件。但要注意Swing并沒有完全取代AWT,它只是替代了AWT包中的UI組件(如Button、TextField等),一些輔助類(如Graphics、Color、Font等)仍然保持不變。Swing圖形界面元素稱為組件,大多數(shù)組件都派生于JComponent類(頂級容器除外)。JComponent類提供了所有組件的通用功能。所有的Swing組件類都定義在javax.swing包中,表12-1列出了Swing常用的組件類。12.1.2組件類

名類

名類

名類

名JButtonJCheckBoxJColorChooserJComboBoxJComponentJDialogJFileChooserJFraneJLabelJListJMenuJMenuBarJMenuItemJOptionPaneJPanelJPasswordFiedJPopupMenuJProgressBarJRadioButtonJRadioButtonMenuItemJScrollBarJScrollPaneJSeparatorJTableJTextAreaJTextFieldJToolTipJTreeSwing組件需要放置到容器中,Swing定義了兩種類型的容器,第一種是頂級容器,如JFrame、JDialog和JApplet(從JDK9開始,JApplet已被廢棄)。這些容器繼承自AWT的Container類,而不是繼承自JComponent類。12.1.3容器Swing還支持輕量級容器,它們繼承自JComponent類,包括JPanel、JScrollPane、JRootPane等。輕量級容器通常用來組織和管理一組相關(guān)的組件,因為輕量級容器可以包含在另一個容器中。每個使用Swing的程序必須至少有一個頂層Swing容器。對GUI應(yīng)用程序來說,一般應(yīng)該有一個主窗口,或稱框架窗口。在Swing中,窗口是由JFrame對象實現(xiàn)的。12.1.4簡單的Swing程序下面程序使用JFrame類創(chuàng)建一個空的框架窗口容器,其上放置一個標(biāo)簽對象,調(diào)用它的方法設(shè)置有關(guān)屬性,最后顯示該窗口。publicclassHelloSwing{publicstaticvoidmain(String[]args){varframe=newJFrame("HelloSwing");varlabel=newJLabel("第一個Swing程序。",SwingConstants.CENTER);frame.setSize(300,100);frame.add(label);frame.setLocationRelativeTo(null);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}面向?qū)ο蟪绦蛟O(shè)計12.2容器布局FlowLayout布局叫流式布局,它是最簡單的布局管理器。容器設(shè)置為這種布局,那么添加到容器中的組件將從左到右,從上到下,一個一個地放置到容器中,一行放不下,放到下一行。下面是FlowLayout類常用的構(gòu)造方法:publicFlowLayout(intalign,inthgap,intvgap)指定添加到容器中組件的對齊方式(align)、水平間距(hgap)和垂直間距(vgap)。對齊方式align的取值必須為下列三者之一:FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER,它們是FlowLayout定義的整型常量。水平間距是指水平方向上兩個組件之間的距離,垂直間距是行之間的距離,單位都是像素。12.2.1FlowLayout布局publicstaticvoidmain(String[]args){varframe=newJFrame("FlowLayoutDemo");//創(chuàng)建一個FlowLayout對象

varlayout=newFlowLayout(FlowLayout.CENTER,10,20);frame.setLayout(layout);//設(shè)置容器的布局管理器

frame.add(newJButton("Button1"));frame.add(newJButton("2"));frame.add(newJButton("Button3"));frame.add(newJButton("Long-NamedButton4"));frame.add(newJButton("Button5"));frame.setSize(300,150);frame.setLocationRelativeTo(null);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}BorderLayout布局叫邊界式布局,它將容器分成上、下、左、右、中5個區(qū)域,每個區(qū)域可放置一個組件或其他容器。中間區(qū)域是在上、下、左、右都填滿后剩下的區(qū)域。BorderLayout布局管理器的構(gòu)造方法有:publicBorderLayout(inthgap,intvgap)參數(shù)hgap和vgap分別指定使用這種布局時組件之間的水平間隔和垂直間隔距離,單位是像素。添加組件使用add(Componentc,intindex)方法,c為添加的組件,index為指定的位置。指定位置需要使用BorderLayout類定義的5個常量:PAGE_START(頁頭)、PAGE_END(頁尾)、LINE_START(行首)、LINE_END(行尾)和CENTER(中部)。如果不指定位置,組件添加到中部位置。12.2.2BorderLayout布局publicstaticvoidmain(String[]args){varframe=newJFrame("BorderLayoutDemo");varjButton1=newJButton("頁頭");varjButton2=newJButton("頁尾");varjButton3=newJButton("行頭");varjButton4=newJButton("行尾");varjTextField=newJTextField("中央");frame.setLayout(newBorderLayout(10,10));//設(shè)置邊界式布局

frame.add(jButton1,BorderLayout.PAGE_START);frame.add(jButton2,BorderLayout.PAGE_END);frame.add(jButton3,BorderLayout.LINE_START);frame.add(jButton4,BorderLayout.LINE_END);frame.add(jTextField,BorderLayout.CENTER);...}GridLayout布局叫網(wǎng)格式布局,這種布局簡單地將容器分成大小相等的單元格,每個單元格可放置一個組件,每個組件占據(jù)單元格的整個空間,調(diào)整容器的大小,單元格大小隨之改變。下面是GridLayout類的常用構(gòu)造方法:publicGridLayout(introws,intcols,inthgap,intvgap)參數(shù)rows和cols分別指定網(wǎng)格布局的行數(shù)和列數(shù),hgap和vgap指定組件的水平間隔和垂直間隔,單位為像素。行和列參數(shù)至少有一個為非0值。向網(wǎng)格布局的容器中添加組件,只需調(diào)用容器的add()方法即可,不用指定位置,系統(tǒng)按照先行后列的次序依次將組件添加到容器中。12.2.3GridLayout布局publicstaticvoidmain(String[]args){varframe=newJFrame("GridLayoutDemo");frame.setLayout(newGridLayout(3,2));//向容器中添加8個按鈕for(vari=1;i<=8;i++){frame.add(newJButton("Button"+i));}frame.setSize(300,150);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}設(shè)計復(fù)雜布局時通常采用容器嵌套的方式,即把組件添加到一個中間容器中,再把中間容器作為組件添加到另一個容器中,從而實現(xiàn)復(fù)雜的布局。12.2.4Jpanel類及容器嵌套使用面板容器作為中間容器構(gòu)建GUI程序的一般做法是:先將組件添加到面板上,然后將面板作為一個組件再添加到頂層容器中。使用面板作為中間容器,首先需要創(chuàng)建面板對象,JPanel的構(gòu)造方法如下:publicJPanel(LayoutManagerlayout)參數(shù)layout指定面板使用的布局管理器對象,缺省將使用默認(rèn)的布局管理器創(chuàng)建一個面板,面板的默認(rèn)的布局管理器是FlowLayout。publicclassFrameAndPanelextendsJFrame{JPanelpanel1=newJPanel(),panel2=newJPanel();

溫馨提示

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

最新文檔

評論

0/150

提交評論