Java語(yǔ)言程序設(shè)計(jì) 課件 第13、14章 輸入輸出、函數(shù)式編程_第1頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第13、14章 輸入輸出、函數(shù)式編程_第2頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第13、14章 輸入輸出、函數(shù)式編程_第3頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第13、14章 輸入輸出、函數(shù)式編程_第4頁(yè)
Java語(yǔ)言程序設(shè)計(jì) 課件 第13、14章 輸入輸出、函數(shù)式編程_第5頁(yè)
已閱讀5頁(yè),還剩172頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

Java語(yǔ)言程序設(shè)計(jì)第13章輸入輸出

1I/O概述23主要內(nèi)容Java語(yǔ)言程序設(shè)計(jì)(第4版)

2022二進(jìn)制I/O流案例:文件加密解密45文本I/O流案例:統(tǒng)計(jì)文件行數(shù)、單詞數(shù)和字符數(shù)6對(duì)象序列化7Files類(lèi)操作Java語(yǔ)言程序設(shè)計(jì)13.1I/O概述輸入/輸出(I/O)是任何程序設(shè)計(jì)語(yǔ)言都提供的功能,Java語(yǔ)言從一開(kāi)始就支持I/O,最初是通過(guò)java.io包中的類(lèi)和接口提供支持的,之后又出現(xiàn)了NIO和NIO.2。概述目前Java支持流式I/O和文件I/O。流式I/O分為輸入流和輸出流。程序?yàn)榱双@得外部數(shù)據(jù),可以在數(shù)據(jù)源(文件、內(nèi)存及網(wǎng)絡(luò)套接字)上創(chuàng)建一個(gè)輸入流,然后用read()方法順序讀取數(shù)據(jù)。類(lèi)似地,程序可以在輸出設(shè)備上創(chuàng)建一個(gè)輸出流,然后用write()方法將數(shù)據(jù)寫(xiě)到輸出流中。所有的數(shù)據(jù)流都是單向的。使用輸入流只能從中讀取數(shù)據(jù);使用輸出流,只能向其寫(xiě)出數(shù)據(jù),如圖13-1所示。概述按照處理數(shù)據(jù)的類(lèi)型分,數(shù)據(jù)流又可分為二進(jìn)制流和文本流,也分別稱(chēng)為字節(jié)流和字符流,它們處理的信息的基本單位分別是字節(jié)和字符。java.io.File類(lèi)用來(lái)表示物理磁盤(pán)上的實(shí)際文件或目錄,但它不表示文件中數(shù)據(jù)。13.1.1File類(lèi)應(yīng)用絕對(duì)文件名是由驅(qū)動(dòng)器字母、完整的路徑以及文件名組成,如D:\study\Hello.txt是Windows系統(tǒng)下的一個(gè)絕對(duì)文件名。相對(duì)文件名是相對(duì)于當(dāng)前工作目錄的。例如,Hello.txt是一個(gè)相對(duì)文件名。如果當(dāng)前工作目錄是D:\study,絕對(duì)文件名是D:\study\Hello.txt。importjava.io.*;publicclassFileDemo{publicstaticvoidmain(String[]args){varfile=newFile("Hello.txt");//此時(shí)文件還不存在!}}編譯并運(yùn)行該程序,當(dāng)查看當(dāng)前目錄,找不能到Hello.txt文件。這說(shuō)明創(chuàng)建一個(gè)File實(shí)例并不是創(chuàng)建實(shí)際的文件,而僅僅創(chuàng)建一個(gè)表示文件的對(duì)象。如果要?jiǎng)?chuàng)建實(shí)際的文件,可使用下面代碼: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類(lèi)最常用操作方法。publicbooleanexists():測(cè)試File對(duì)象是否存在。publiclonglength():返回指定文件的字節(jié)長(zhǎng)度,文件不存在時(shí)返回0。publicbooleancreateNewFile():當(dāng)文件不存在時(shí),創(chuàng)建一個(gè)空文件時(shí)返回true,否則返回false。publicbooleanrenameTo(FilenewName):重新命名指定的文件對(duì)象,正常重命名時(shí)返回true,否則返回false。publicbooleandelete():刪除指定的文件。若為目錄,當(dāng)目錄為空才能刪除。publiclonglastModified():返回文件最后被修改的日期和時(shí)間,它計(jì)算的是從1970年1月1日0時(shí)0分0秒開(kāi)始的毫秒數(shù)。13.1.1File類(lèi)應(yīng)用文件通常可以分為文本文件和二進(jìn)制文件。文本文件(textfile)是包含字符序列的文件,可以使用文本編輯器查看或通過(guò)程序閱讀。內(nèi)容必須按二進(jìn)制序列處理的文件稱(chēng)為二進(jìn)制文件(binaryfile)。13.1.2文本I/O與二進(jìn)制I/O實(shí)際上,計(jì)算機(jī)并不區(qū)分二進(jìn)制文件與文本文件。所有的文件都是以二進(jìn)制形式來(lái)存儲(chǔ)的,因此,從本質(zhì)上說(shuō),所有的文件都是二進(jìn)制文件。對(duì)于文本I/O而言,在寫(xiě)入一個(gè)字符時(shí),Java虛擬機(jī)會(huì)將字符的統(tǒng)一碼轉(zhuǎn)換為文件指定的編碼,在讀取字符時(shí),將文件指定的編碼轉(zhuǎn)換為統(tǒng)一碼。13.1.2文本I/O與二進(jìn)制I/O使用文本I/O將字符串“123”寫(xiě)入文件,那么每個(gè)字符的二進(jìn)制編碼都會(huì)寫(xiě)入到文件。二進(jìn)制I/O不需要進(jìn)行轉(zhuǎn)換。如果使用二進(jìn)制I/O向文件寫(xiě)入一個(gè)數(shù)據(jù),就是將內(nèi)存中的值復(fù)制到文件中。13.1.2文本I/O與二進(jìn)制I/O例如,一個(gè)byte類(lèi)型的數(shù)值123在內(nèi)存中表示為01111011,將它寫(xiě)入文件也是01111011。使用二進(jìn)制I/O讀取一個(gè)字節(jié)時(shí),就會(huì)從輸入流中讀取一個(gè)字節(jié)的二進(jìn)制編碼。Java語(yǔ)言程序設(shè)計(jì)13.2二進(jìn)制I/O流6.1.1publicintread()publicintread(byte[]b)publicvoidclose()InputStream類(lèi)是二進(jìn)制輸入流的根類(lèi),它有多個(gè)子類(lèi)。InputStream類(lèi)和OutputStream類(lèi)Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:2886394866.1.1

publicvoidwrite(intb)publicvoidwrite(byte[]b)publicvoidclose()OutputStream類(lèi)是二進(jìn)制輸出流的根類(lèi),它有多個(gè)子類(lèi)。Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486InputStream類(lèi)和OutputStream類(lèi)FileInputStream類(lèi)和FileOutputStream類(lèi)用來(lái)實(shí)現(xiàn)文件的輸入輸出處理。13.2.2FileOutputStream類(lèi)和FileInputStream類(lèi)FileInputStream類(lèi)和FileOutputStream類(lèi)都實(shí)現(xiàn)了java.lang.AutoClosable接口,因此可以在try-with-resources語(yǔ)句中使用,當(dāng)流使用完自動(dòng)將它們關(guān)閉。FileOutputStream類(lèi)的常用構(gòu)造方法如下:FileOutputStream(Stringname):用表示文件的字符串創(chuàng)建文件輸出流對(duì)象。FileOutputStream(Stringname,booleanappend):用表示文件的字符串創(chuàng)建文件輸出流對(duì)象。如果append參數(shù)為true,則指明打開(kāi)的文件輸出流不覆蓋原來(lái)的內(nèi)容,而是從文件末尾寫(xiě)入新內(nèi)容,否則覆蓋原來(lái)的文件內(nèi)容。FileOutputStream(Filefile):用File對(duì)象創(chuàng)建文件輸出流對(duì)象。13.2.2FileOutputStream類(lèi)和FileInputStream類(lèi)FileInputStream類(lèi)的兩個(gè)常用的構(gòu)造方法如下:

FileInputStream(Stringname):用表示文件的字符串創(chuàng)建文件輸入流對(duì)象。FileInputStream(Filefile):用File對(duì)象創(chuàng)建文件輸入流對(duì)象。13.2.2FileOutputStream類(lèi)和FileInputStream類(lèi)若指定的文件不存在,則產(chǎn)生FileNotFoundException異常,它是檢查異常,必須捕獲或聲明拋出。也可以先創(chuàng)建File對(duì)象,然后測(cè)試該文件是否存在,若存在再創(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("已向文件寫(xiě)入10個(gè)兩位數(shù)!");}catch(IOExceptione){System.out.println(e.toString());}}程序13.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());}

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

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

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

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

newBufferedOutputStream(output));

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

}程序13.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類(lèi)為打印各種類(lèi)型的數(shù)據(jù)提供了方便。PrintStream類(lèi)定義了多個(gè)print()和println()方法,可以打印輸出各種類(lèi)型的數(shù)據(jù),這些方法都是把數(shù)據(jù)轉(zhuǎn)換成字符串,然后輸出。如果輸出到文件中則可以用記事本瀏覽。println()方法輸出后換行,print()方法輸出后不換行。13.2.5PrintStream類(lèi)當(dāng)把對(duì)象傳遞給這兩個(gè)方法時(shí)則先調(diào)用對(duì)象的toString()方法將對(duì)象轉(zhuǎn)換為字符串形式,然后輸出。在前面章節(jié)大量使用的System.out對(duì)象就是PrintStream類(lèi)的一個(gè)實(shí)例,用于向控制臺(tái)輸出數(shù)據(jù)。Java在System類(lèi)中定義了標(biāo)準(zhǔn)輸出流out,標(biāo)準(zhǔn)輸入流in以及標(biāo)準(zhǔn)錯(cuò)誤輸出流err,如下所示。13.2.6標(biāo)準(zhǔn)輸入輸出流publicstaticfinaljava.io.PrintStreamout;publicstaticfinaljava.io.InputStreamin;publicstaticfinaljava.io.PrintStreamerr;System.in是InputStream類(lèi)的實(shí)例??梢允褂胷ead()方法從鍵盤(pán)上讀取字節(jié),也可以將它包裝成數(shù)據(jù)流讀取各種類(lèi)型的數(shù)據(jù)和字符串。System.out和System.err是PrintStream類(lèi)的實(shí)例,可以使用該類(lèi)定義的方法輸出各種類(lèi)型數(shù)據(jù)。6.1.1問(wèn)題描述編寫(xiě)程序,隨機(jī)生成10個(gè)1000到2000之間的整數(shù),將它們寫(xiě)到一個(gè)文件data.dat中,然后從該文件中讀出這些整數(shù),要求使用DataInputStream和DataOutputStream類(lèi)實(shí)現(xiàn)。課堂討論與訓(xùn)練Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486Java語(yǔ)言程序設(shè)計(jì)13.3案例:文件加密解密編寫(xiě)一個(gè)簡(jiǎn)單的文件加密、解密程序。文件加密、解密有多種方法,本案例使用一種簡(jiǎn)單的算法,對(duì)文件的內(nèi)容使用“異或”運(yùn)算進(jìn)行加密后保存到指定的文件中。要對(duì)文件解密,讀取文件中的加密內(nèi)容,再次使用“異或”運(yùn)算解密得到原文件內(nèi)容。文件加密解密本案例使用“異或”運(yùn)算對(duì)文件中字節(jié)進(jìn)行加密、解密的原理可以描述如下:按位“異或”運(yùn)算符的運(yùn)算規(guī)則是:兩個(gè)操作數(shù)中,如果相應(yīng)位相同,則結(jié)果為0,否則為1,例如:00101010^00010111=00111101“異或”運(yùn)算符的特點(diǎn)是:用同一個(gè)數(shù)b對(duì)操作數(shù)a進(jìn)行兩次“異或”運(yùn)算,結(jié)果仍然為原值a。就是,如果c=a^b,那么a=c^b,即用同一個(gè)數(shù)b對(duì)數(shù)a進(jìn)行兩次“異或”運(yùn)算的結(jié)果又是數(shù)a。利用“異或”運(yùn)算的這個(gè)性質(zhì),可以實(shí)現(xiàn)簡(jiǎn)單的字節(jié)加密、解密操作。文件加密解密(1)程序首先要求用戶輸入要加密的文件名、加密后的文件名以及加密使用的秘鑰,也就是要在讀取的字節(jié)上做“異或”運(yùn)算的整數(shù)。(2)使用FileInputStream和FileOutputStream創(chuàng)建輸入流(源文件)和輸出流(加密文件),從源文件讀取每個(gè)字節(jié)然后對(duì)它做“異或”運(yùn)算,將結(jié)果寫(xiě)入加密的文件。文件加密解密(3)文件解密的過(guò)程與加密的過(guò)程類(lèi)似。使用FileInputStream和FileOutputStream創(chuàng)建輸入流(要解密的文件)和輸出流(解密后文件),從輸入流讀取每個(gè)字節(jié)然后對(duì)它做“異或”運(yùn)算,將結(jié)果寫(xiě)入解密后的文件。這里要注意,解密使用的秘鑰需與加密使用的秘鑰相同,否則得不到源文件。varinput=newScanner(System.in);StringsourceFile=null;StringsecretFile=null;varkeyValue=0;System.out.print("請(qǐng)輸入源文件名:");sourceFile=input.nextLine();System.out.print("請(qǐng)輸入加密文件名:");secretFile=input.nextLine();System.out.print("請(qǐng)輸入秘鑰:");keyValue=input.nextInt();程序13.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("請(qǐng)輸入要解密文件:");secretFile=input.nextLine();System.out.print("請(qǐng)輸入解密后文件名:");resultFile=input.nextLine();System.out.print("請(qǐng)輸入秘鑰:");keyValue=input.nextInt();程序13.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();

}

}Java語(yǔ)言程序設(shè)計(jì)13.4文本I/O流文本I/O流以字符為基本單位,也叫字符I/O流。抽象類(lèi)Reader和Writer分別是文本輸入流和輸出流的根類(lèi)。概述概述Writer類(lèi)是字符輸出流的根類(lèi),定義的常用方法有:publicvoidwrite(intc):向輸出流中寫(xiě)一個(gè)字符,實(shí)際是將int型的c的低16位寫(xiě)入輸出流。publicvoidwrite(Stringstr):把字符串str寫(xiě)入輸出流中。publicvoidclose():關(guān)閉輸出流。13.4.1Reader類(lèi)和Writer類(lèi)Reader類(lèi)是文本輸入流的根類(lèi),定義的常用方法有:

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

FileWriter(StringfileName)

FileWriter(Filefile)FileWriter(StringfileName,booleanappend)下面的FileCopyDemo.java程序使用FileReader和FileWriter將文件input.txt(在項(xiàng)目跟目錄下)的內(nèi)容復(fù)制到output.txt文件中。13.4.2FileWriter類(lèi)和FileReader類(lèi)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());

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

varin=newBufferedReader(newFileReader("input.txt"));BufferedWriter類(lèi)的構(gòu)造方法如下:BufferedWriter(Writerout):用默認(rèn)的緩沖區(qū)大小創(chuàng)建緩沖字符輸出流。BufferedWriter(Writerout,intsz):用指定的緩沖區(qū)大小創(chuàng)建緩沖字符輸出流。13.4.3BufferedReader類(lèi)和BufferedWriter類(lèi)通常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);程序13.5WordsCount.javaPrintWriter類(lèi)實(shí)現(xiàn)字符打印輸出流,它的構(gòu)造方法如下:PrintWriter(Writerout):使用參數(shù)指定的輸出流對(duì)象out創(chuàng)建一個(gè)打印輸出流。PrintWriter(Writerout,booleanautoFlush):如果autoFlush指定為true,則在輸出之前自動(dòng)刷新輸出流。13.4.4PrintWriter類(lèi)PrintWriter類(lèi)定義的常用方法如下。publicvoidprintln(booleanb):輸出一個(gè)boolean型數(shù)據(jù)。publicvoidprintln(Strings):輸出一個(gè)String型數(shù)據(jù)。publicvoidprintln(Objectobj):將obj轉(zhuǎn)換成String型數(shù)據(jù),然后輸出。下面程序隨機(jī)產(chǎn)生10個(gè)100到200之間的整數(shù),然后使用PrintWriter對(duì)象輸出到文件number.txt中。13.4.4PrintWriter類(lèi)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);//向文件中隨機(jī)寫(xiě)入10個(gè)隨機(jī)整數(shù)for(vari=0;i<10;i++){varnum=(int)(Math.random()*101)+100;pw.println(num);}pw.close();程序13.6PrintWriterDemo.java//從文件中讀出10個(gè)整數(shù)varin=newFileReader(newFile(fileName));varreader=newBufferedReader(in);varaLine=reader.readLine();while(aLine!=null){System.out.print(aLine+"");aLine=reader.readLine();}reader.close();該程序運(yùn)行后在項(xiàng)目目錄下創(chuàng)建一個(gè)number.txt文本文件,并且寫(xiě)入10個(gè)整數(shù),該文件可以用記事本打開(kāi)。使用Scanner類(lèi)從鍵盤(pán)讀取數(shù)據(jù),這是在創(chuàng)建Scanner對(duì)象時(shí)將標(biāo)準(zhǔn)輸入設(shè)備System.in作為其構(gòu)造方法的參數(shù)。使用Scanner還可以關(guān)聯(lián)文本文件,從文本文件中讀取數(shù)據(jù)。13.4.5使用Scanner對(duì)象Scanner類(lèi)的常用的構(gòu)造方法有:publicScanner(Stringsource):用指定的字符串構(gòu)造Scanner對(duì)象,以便從中讀取數(shù)據(jù)。publicScanner(InputStreamsource):用指定的輸入流構(gòu)造一個(gè)Scanner對(duì)象,以便從中讀取數(shù)據(jù)。Scanner類(lèi)的常用方法如下所示:publicbytenextByte():讀取下一個(gè)標(biāo)記并將其解析成byte型數(shù)。publicintnextInt():讀取下一個(gè)標(biāo)記并將其解析成int型數(shù)。publicdoublenextDouble():讀取下一個(gè)標(biāo)記并將其解析成double型數(shù)。publicStringnext():讀取下一個(gè)標(biāo)記并將其解析成字符串。publicStringnextLine():讀取當(dāng)前行作為一個(gè)String型字符串。13.4.5使用Scanner對(duì)象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();} 程序13.7TextFileDemo.javaJava語(yǔ)言程序設(shè)計(jì)13.5案例:統(tǒng)計(jì)文件行數(shù)、單詞數(shù)和字符數(shù)經(jīng)常需要對(duì)文本文件分析,比如查找有關(guān)內(nèi)容,進(jìn)行某種統(tǒng)計(jì)等。本案例要求編寫(xiě)程序,統(tǒng)計(jì)一個(gè)英文文本文件中的字符數(shù)、單詞數(shù)和行數(shù)。單詞由空格和逗號(hào)、句號(hào)、分號(hào)和感嘆號(hào)這幾個(gè)個(gè)標(biāo)點(diǎn)符號(hào)分隔,文件名由鍵盤(pán)讀入。統(tǒng)計(jì)文件行數(shù)、單詞數(shù)和字符數(shù)(1)創(chuàng)建Scanner對(duì)象,從鍵盤(pán)讀取要統(tǒng)計(jì)的源文件名,并判斷文件是否存在,存在繼續(xù),不存在則強(qiáng)制程序結(jié)束。(2)創(chuàng)建FileReader和BufferedReader對(duì)象,使用readLine()方法從指定的文件讀取字符串進(jìn)行解析。(3)對(duì)每一行的字符串,用String的length()方法計(jì)算字符數(shù),再使用String類(lèi)的split()方法根據(jù)置分隔符來(lái)解析所包含的單詞數(shù)。

varinput=newScanner(System.in);

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

varfile=newFile(filename);

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

}程序13.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個(gè)符號(hào)wordsNums=wordsNums+words.length;lineNums=lineNums+1;aLine=fis.readLine();

}

System.out.println("文件="

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

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

+wordsNums+"個(gè)"

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

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

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

oos.writeInt(2022);

oos.writeObject("你好");

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

var

fis=newFileInputStream("data.ser");

var

oip=newObjectInputStream(fis);

int

i=ois.readInt();

vartoday=(String)ois.readObject();

vardate=(LocalDate)ois.readObject();下面的例子說(shuō)明如何實(shí)現(xiàn)對(duì)象的序列化和反序列化,這里的對(duì)象是Customer記錄類(lèi)型的對(duì)象,它實(shí)現(xiàn)了Serializable接口。關(guān)于記錄類(lèi)型,請(qǐng)參閱11.1節(jié)。示例:對(duì)象序列化和反序列化程序13.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);//寫(xiě)入一個(gè)客戶對(duì)象 oos.writeObject(today);//寫(xiě)入一個(gè)日期對(duì)象}catch(IOExceptione){ e.printStackTrace();}程序13.9ObjectSerializeDemo.javatry(varinput=newFileInputStream("D:\\study\\customer.dat");varois=newObjectInputStream(input)){while(true){ try{ customer=(Customer)ois.readObject(); System.out.println("客戶號(hào):"+customer.id()); System.out.println("姓名:"+()); System.out.println("地址:"+customer.address());today=(LocalDate)ois.readObject(); System.out.println("日期:"+today); }catch(EOFExceptione){}如果數(shù)組中的所有元素都是可序列化的,這個(gè)數(shù)組就是可序列化的。一個(gè)完整的數(shù)組可以用writeObject()方法存入文件,之后用readObject()方法讀取到程序中。13.6.4序列化數(shù)組下面程序?qū)⒁粋€(gè)有5個(gè)元素的int型數(shù)組和一個(gè)有3個(gè)元素的String型數(shù)組存儲(chǔ)到文件中,然后將它們從文件中讀取出顯示在控制臺(tái)上。try{int[]numbers={1,2,3,4,5};String[]cities={"北京","上海","廣州"};//序列化try(varoutput=newFileOutputStream("array.dat",true);varoos=newObjectOutputStream(output);){ oos.writeObject(numbers);//將numbers數(shù)組寫(xiě)入文件 oos.writeObject(cities);//將cities數(shù)組寫(xiě)入文件}catch(IOExceptione){e.printStackTrace(); }程序13.10ArraySerialDemo.javatry(//反序列化varinput=newFileInputStream("array.dat");varois=newObjectInputStream(input);){//讀取數(shù)組對(duì)象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+"");Java語(yǔ)言程序設(shè)計(jì)13.7Files類(lèi)操作為了增強(qiáng)JavaI/O功能,在新的JDK中增加了一些新的API處理I/O操作,主要包括java.nio包及其子包,以及java.nio.file包及其子包。概述java.nio.file.Files類(lèi)是一個(gè)功能非常強(qiáng)大的類(lèi)。該類(lèi)定義了大量的靜態(tài)方法用來(lái)讀、寫(xiě)和操縱文件和目錄。Files類(lèi)主要操作Path對(duì)象,下面首先介紹Path接口,然后學(xué)習(xí)Files在Java7之前,用File對(duì)象表示文件和目錄。由于使用File類(lèi)存在著許多不足,因此在Java7中應(yīng)使用java.nio.file.Path接口代替File。Path對(duì)象在文件系統(tǒng)中表示文件或目錄。它表示一個(gè)路徑,可以是一個(gè)文件、一個(gè)目錄,它還可以表示一個(gè)根目錄13.7.1Path對(duì)象在Windows系統(tǒng)中,Path對(duì)象使用Windows語(yǔ)法表示(如,D:\study\com\demo)。有多種方式創(chuàng)建和操作Path實(shí)例,可以把一個(gè)Path對(duì)象追加到另一個(gè)Path對(duì)象上、抽取Path對(duì)象部分內(nèi)容、與另一個(gè)Path對(duì)象比較等。Path實(shí)例包含確定文件或目錄位置的信息。在創(chuàng)建Path實(shí)例時(shí),通常要提供一系列名稱(chēng),如根元素或文件名等。一個(gè)Path可以只包含路徑名或文件名。可以使用Paths(注意是復(fù)數(shù))類(lèi)的get()方法創(chuàng)建Path對(duì)象:1.創(chuàng)建Path實(shí)例varp1=Paths.get("D:\\study\\com\\Hello.java");varp2=Paths.get(args[0]);varp3=Paths.get(URI.create("file:///users/joe/FileTest.java"));Path對(duì)象可以看做是一個(gè)名稱(chēng)序列,每一級(jí)目錄可以通過(guò)索引指定。目錄結(jié)構(gòu)的最頂層索引為0,目錄結(jié)構(gòu)的最底層元素索引是n-1,n是總層數(shù)。例如,getName(0)方法將返回最頂層目錄名稱(chēng)。下面代碼演示了Path接口的幾個(gè)方法。2.檢索路徑信息varpath=Paths.get("D:\\study\\user\\report.txt");System.out.println("toString:"+path.toString());System.out.println("getFileName:"+path.getFileName());System.out.println("getName(0):"+path.getName(0));System.out.println("getNameCount:"+path.getNameCount());System.out.println("subpath(0,2):"+path.subpath(0,2));System.out.println("getParent:"+path.getParent());System.out.println("getRoot:"+path.getRoot());Files類(lèi)提供了下面的方法創(chuàng)建、刪除目錄和文件:13.7.2創(chuàng)建和刪除目錄及文件staticPathcreateDirectory(Pathdir,FileAttribute<?>…attrs):創(chuàng)建由dir指定的目錄,如果創(chuàng)建的目錄已經(jīng)存在,該方法將拋出FileAlreadyExistsException異常。staticPathcreateFile(Pathfile,FileAttribute<?>…attrs)

staticvoiddelete(Pathpath)staticvoiddeleteIfExists(Pathpath)try{Files.delete(path);}catch(NoSuchFileExceptionx){System.out.println("Nosuchfile"+path);}catch(DirectoryNotEmptyExceptionx){System.err.format("Thedirectoryisnotempty");}catch(IOExceptionx){//文件許可問(wèn)題在此捕獲System.err.println(x);}可以使用Files類(lèi)的方法檢查Path對(duì)象表示的文件或目錄是否存在、是否可讀、是否可寫(xiě)、是否可執(zhí)行等。13.7.3文件屬性操作staticbooleanexists(Pathpath,LinkOption…options)staticbooleannotExists(Pathpath,LinkOption…options)staticbooleanisReadable(Pathpath)staticbooleanisWritable(Pathpath)staticbooleanisExecutable(Pathpath)booleanisRegularFile(Pathpath,LinkOption...options)Files類(lèi)中包含了下面一些方法獲得或設(shè)置文件的一個(gè)屬性。13.7.3文件屬性操作staticlongsize(Pathpath):返回指定文件的字節(jié)大小。staticbooleanisDirectory(Pathpath,LinkOption…options)staticbooleanisHidden(Pathpath)staticFileTimegetLastModifiedTime(Pathpath,LinkOption...options)staticPathsetLastModifiedTime(Pathpath,FileTime)staticUserPrincipalgetOwner(Pathpath,LinkOption...options)6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486復(fù)制、移動(dòng)目錄與文件使用Files類(lèi)的copy()方法可以復(fù)制文件和目錄。staticPathcopy(Pathsource,Pathtarget,CopyOption…options)StandardCopyOption枚舉是CopyOption接口的一個(gè)實(shí)現(xiàn):ATOMIC_MOVECOPY_ATTRIBUTESREPLACE_EXISTING6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486復(fù)制、移動(dòng)目錄與文件Pathsource=Paths.get("D:\\study\\demo\\report.txt"),target=Paths.get("D:\\study\\demo\\backup.txt");try{Files.copy(source,target,StandardCopyOption.REPLACE_EXISTING);}catch(NoSuchFileExceptionnse){nse.printStackTrace();}catch(IOExceptionioe){ioe.printStackTrace();}6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486復(fù)制、移動(dòng)目錄與文件使用Files類(lèi)的move()方法可以移動(dòng)或重命名文件或目錄,格式如下:staticPathmove(Pathsource,Pathtarget,CopyOption…options)StandardCopyOption枚舉是CopyOption接口的一個(gè)實(shí)現(xiàn):ATOMIC_MOVECOPY_ATTRIBUTESREPLACE_EXISTING6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486復(fù)制、移動(dòng)目錄與文件以下代碼將C:\temp\backup.bmp文件移到C:\data目錄中。Pathsource=Paths.get("C:\\temp\\backup.bmp");Pathtarget=Paths.get("C:\\data\\backup.bmp");try{

Files.move(source,target,StandardCopyOption.REPLACE_EXISTING);}catch(IOExceptione){

e.printStackTrace();}6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:28863948613.7.6小文件的讀寫(xiě)Files類(lèi)提供了對(duì)較小的二進(jìn)制文件和文本文件讀取和寫(xiě)入的方法。staticPathwrite(Pathpath,byte[]bytes,OpenOption…options)StandardOpenOption枚舉是OpenOption接口的一個(gè)實(shí)現(xiàn):APPEND,CREATECREATE_NEW,DELETE_ON_CLOSEREAD,WRITE,TRUNCATE_EXISTING6.1.1下面方法向文件寫(xiě)入若干行。staticPathwrite(Pathpath,Iterable<extendsCharSequence>lines,Charsetcs,OpenOption…options)13.7.6小文件的讀寫(xiě)6.1.1使用下面方法可以從文件讀取所有字節(jié)或行:staticbyte[]readAllBytes(Pathpath)staticList<String>readAllLines(Pathpath,Charsetcs)

13.7.6小文件的讀寫(xiě)6.1.1Java語(yǔ)言程序設(shè)計(jì)(第4版)

QQ群:288639486使用Files類(lèi)創(chuàng)建流對(duì)象調(diào)用Files.newInputStream()靜態(tài)方法獲得與文件關(guān)聯(lián)的InputStream對(duì)象來(lái)讀取數(shù)據(jù)。調(diào)用Files.newOutputStream()靜態(tài)方法獲得與文件關(guān)聯(lián)的OutputStream對(duì)象向文件寫(xiě)數(shù)據(jù)。6.1.1newInputStream()方法格式如下:

staticInputStreamnewInputStream(Pathpath,OpenOption…options)throwsIOException6.1.1

Pathpath=Paths.get("src\\output.dat");try(InputStreaminput=Files.newInputStream(path,

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論