Java程序設(shè)計(jì)基礎(chǔ)教程(慕課版)(第2版) 課件 朱麗萍 第7-12單元 文件及流 -綜合實(shí)訓(xùn)-簡易網(wǎng)上銀行系統(tǒng)_第1頁
Java程序設(shè)計(jì)基礎(chǔ)教程(慕課版)(第2版) 課件 朱麗萍 第7-12單元 文件及流 -綜合實(shí)訓(xùn)-簡易網(wǎng)上銀行系統(tǒng)_第2頁
Java程序設(shè)計(jì)基礎(chǔ)教程(慕課版)(第2版) 課件 朱麗萍 第7-12單元 文件及流 -綜合實(shí)訓(xùn)-簡易網(wǎng)上銀行系統(tǒng)_第3頁
Java程序設(shè)計(jì)基礎(chǔ)教程(慕課版)(第2版) 課件 朱麗萍 第7-12單元 文件及流 -綜合實(shí)訓(xùn)-簡易網(wǎng)上銀行系統(tǒng)_第4頁
Java程序設(shè)計(jì)基礎(chǔ)教程(慕課版)(第2版) 課件 朱麗萍 第7-12單元 文件及流 -綜合實(shí)訓(xùn)-簡易網(wǎng)上銀行系統(tǒng)_第5頁
已閱讀5頁,還剩264頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第7單元文件及流Java程序設(shè)計(jì)基礎(chǔ)教程((慕課版)(第2版))目錄導(dǎo)航7.1

File類7.3項(xiàng)目實(shí)戰(zhàn)7.2輸入輸出流7.4單元小結(jié)7.1.1File類的常用方法表7-1File類的常用方法方法名稱方法說明File(Fileparent,Stringchild)創(chuàng)建一個(gè)File對(duì)象,該對(duì)象的路徑由parent的絕對(duì)路徑與child字符串組成,代表一個(gè)新的目錄或文件路徑File(StringpathName)創(chuàng)建一個(gè)File對(duì)象,將pathName的指定路徑轉(zhuǎn)換成絕對(duì)路徑File(URLurl)創(chuàng)建一個(gè)File對(duì)象,將URL(UniformResourceLocator,統(tǒng)一資源定位符)轉(zhuǎn)換成絕對(duì)路徑booleancanRead()判斷文件是否可讀booleancanWrite()判斷文件是否可寫booleancreateNewFile()創(chuàng)建一個(gè)文件或目錄booleandelete()刪除一個(gè)文件booleanexist()判斷文件是否存在StringgetName()獲取文件或目錄的名字booleanisDirectory()判斷當(dāng)前對(duì)象是否是目錄booleanisFile()判斷當(dāng)前對(duì)象是否是文件booleanisHidden()判斷文件是否是隱藏文件longlastModified()文件最后一次修改時(shí)間longlength()返回文件的長度String[]list()返回當(dāng)前對(duì)象所代表的目錄下的所有文件和目錄列表File[]listFiles()返回當(dāng)前對(duì)象所代表的目錄下的所有文件列表File[]listFiles(FileFilterfilter)返回當(dāng)前對(duì)象所代表的目錄下的文件列表,要求符合過濾規(guī)則booleanmkdir()創(chuàng)建目錄booleanrenameTo(Filedest)將文件改名成dest對(duì)象所指示的名字booleansetLastModified(longtime)設(shè)置文件或目錄的最后修改時(shí)間booleansetReadOnly()將文件或目錄設(shè)置成可讀7.1.1File類的常用方法下面通過任務(wù)7-1來了解創(chuàng)建與刪除文件的操作。01OPTION文件的創(chuàng)建與刪除為了獲取文件的固有屬性,例如文件的路徑、內(nèi)容長度和是否隱藏等,可在項(xiàng)目路徑下創(chuàng)建一個(gè).txt文件,名稱是InherenetAttributeTest;然后在里面寫一些內(nèi)容,如“Thisfileisthetestforfile'sinherentattribute.”,讓getlength()方法不返回0。

下面通過任務(wù)7-2了解如何獲取文件的固有屬性。文件的固有屬性02OPTION文件的可變屬性03OPTION文件的有些屬性是可以被修改的,這些內(nèi)容包含文件的可讀性、可寫性和最后修改時(shí)間等。

下面通過任務(wù)7-3來了解如何獲取文件的可變屬性。任務(wù)7-1文件的創(chuàng)建與刪除文件FileCreateAndDelDemo.javaimportjava.io.File;importjava.io.IOException;publicclassFileCreateAndDelDemo{publicstaticvoidmain(String[]args){Filefile=newFile("Hello.txt");//創(chuàng)建一個(gè)文件類型對(duì)象Filedir=newFile("\\creatDir");System.out.println("文件是否存在:"+file.exists());System.out.println("文件夾是否存在:"+dir.exists());if(!file.exists()){try{file.createNewFile();//如果文件不存在,則創(chuàng)建一個(gè)新的文件}catch(IOExceptione){e.printStackTrace();}}if(!dir.exists()){dir.mkdir();//如果文件夾不存在,則創(chuàng)建一個(gè)文件夾}System.out.println("文件是否存在:"+file.exists());System.out.println("文件夾是否存在:"+dir.exists());System.out.println("文件的絕對(duì)路徑是:"+file.getAbsolutePath());System.out.println("文件夾的絕對(duì)路徑是:"+dir.getAbsolutePath());file.delete();//刪除文件System.out.println("文件是否存在:"+file.exists());}}運(yùn)行結(jié)果如圖7-1所示。文件對(duì)象是通過newFile("文件路徑")的方式創(chuàng)建的,但是創(chuàng)建之前虛擬機(jī)不知道這個(gè)文件是否存在。文件是否存在是使用File類的exists()方法來判斷的。如果文件不存在,可以使用createNewFile()方法創(chuàng)建一個(gè)這樣的文件。如果文件存在,但這個(gè)文件是一個(gè)文件夾而非一個(gè)文件,如果將此以文件類型而非文件夾類型進(jìn)行處理,也會(huì)拋出文件找不到的異常。文件的刪除比較簡單,直接調(diào)用File對(duì)象的delete()方法就可以了。任務(wù)7-2獲取文件的固有屬性文件FileInherentAttributeDemo.javaimportjava.io.File;publicclassFileInherentAttributeDemo{publicstaticvoidmain(String[]args){Filefile=newFile("InherenetAttributeTest.txt");if(file.exists()){System.out.println("文件的長度:"+file.length());System.out.println("文件的絕對(duì)路徑:"+file.getAbsolutePath());System.out.println("文件的相對(duì)路徑:"+file.getPath());System.out.println("文件是否是隱藏文件:"+file.isHidden());System.out.println("是否是文件類型:"+file.isFile());System.out.println("是否是文件夾類型:"+file.isDirectory());}}}運(yùn)行結(jié)果如圖7-2所示。任務(wù)7-3獲取文件的可變屬性文件FileVariableAttributeDemo.javaimportjava.io.File;publicclassFileVariableAttributeDemo{publicstaticvoidmain(String[]args){Filefile=newFile("InherenetAttributeTest.txt");//創(chuàng)建文件對(duì)象if(file.exists()){//判斷文件是否存在System.out.println("文件是否可讀:"+file.canRead());System.out.println("文件是否可寫:"+file.canWrite());System.out.println("文件上一次修改的時(shí)間(系統(tǒng)當(dāng)前毫秒值):"+file.lastModified());file.setReadable(!file.canRead());//設(shè)置文件是否可讀file.setWritable(!file.canWrite());//設(shè)置文件是否可寫file.setLastModified(0);//設(shè)置文件的最后修改時(shí)間(毫秒值)System.out.println("文件是否可讀:"+file.canRead());System.out.println("文件是否可寫:"+file.canWrite());System.out.println("文件上一次修改的時(shí)間(系統(tǒng)當(dāng)前毫秒值):"+file.lastModified());}}}運(yùn)行結(jié)果如圖7-3所示。Java中的文件包含文件夾,所以有時(shí)候要判斷一個(gè)路徑是指向一個(gè)普通文件還是一個(gè)文件夾。如果把一個(gè)文件夾當(dāng)作文件去處理,會(huì)引發(fā)FileNotFoundException異常。這個(gè)異常并非是因?yàn)樵撐募淮嬖?,也可能是誤把文件夾當(dāng)成文件處理了。7.1.2目錄文件遍歷下面通過任務(wù)7-4了解如何獲取子文件列表和目錄。01OPTION獲取子文件列表和目錄下面通過任務(wù)7-5了解如何獲取目錄下的所有文本文件并輸出。獲取目錄下的所有文本文件并輸出02OPTION刪除文件夾03OPTION文件夾的刪除需要使用到遞歸的思想,即如果是文件夾,就一直遞歸,直到碰到空文件夾或者只有文件的文件夾。為了便于演示,我們首先選擇一個(gè)需要?jiǎng)h除的文件夾,然后將此文件夾復(fù)制到另一個(gè)位置,再進(jìn)行刪除,直到剩下一個(gè)空文件夾為止。為了便于操作,筆者將C盤下C:\Windows\AppPatch文件夾復(fù)制到E盤根目錄下,具體信息如圖所示。目錄文件也是文件夾,文件夾中會(huì)有子文件夾和子文件,子文件夾中有可能也有子文件或者子文件夾,所以對(duì)一個(gè)文件夾的遍歷應(yīng)當(dāng)是一個(gè)遞歸的過程。如果只對(duì)一個(gè)文件夾下的所有文件夾和文件進(jìn)行遍歷則比較簡單。任務(wù)7-4獲取子文件列表和目錄文件IteratorFilesDemo.javaimportjava.io.File;publicclassIteratorFilesDemo{publicstaticvoidmain(String[]args){Filefile=newFile("C:\\Users");//獲取Users目錄對(duì)象if(file.exists()){//如果文件或目錄存在String[]files=file.list();//獲取目錄下的文件和目錄的名稱for(StringfileName:files){System.out.println(fileName);}System.out.println("***********************************");File[]subFiles=file.listFiles();//獲取文件列表for(Filef:subFiles){if(f.isDirectory()){//如果是目錄System.out.println("|—"+f.getName());}else{//如果是文件System.out.println("-"+f.getName());}}}}}運(yùn)行結(jié)果如圖7-4所示。如果只是單純獲取子文件的名稱,使用list()方法即可。該方法可以獲取子文件的名稱列表,包含子文件和子文件夾,返回的是一個(gè)字符串?dāng)?shù)組,在簡單遍歷時(shí)比較方便。如果需要對(duì)子文件進(jìn)行處理,則使用listFiles()方法更加有效。listFiles()方法還支持過濾,讀者可以給定過濾規(guī)則,過濾掉不需要的文件對(duì)象。任務(wù)7-5獲取目錄下的所有文本文件并輸出文件FilterFileDemo.javaimportjava.io.File;importjava.io.FilenameFilter;publicclassFilterFileDemo{publicstaticvoidmain(String[]args){Filefile=newFile("C:/ProgramFiles/Intel/MediaSDK");//自定義一個(gè)文件過濾器,用于篩選以.dll結(jié)尾的文件FilenameFilterfilter=newFilenameFilter(){@Overridepublicbooleanaccept(Filedir,Stringname){FilecurFile=newFile(dir,name);//只有文件真實(shí)存在且以.dll結(jié)尾才返回true,否則返回falseif(curFile.isFile()&&name.endsWith(".dll")){returntrue;}returnfalse;}};//使用自定義的過濾器過濾文件File[]files=file.listFiles(filter);for(Filef:files){//循環(huán)輸出System.out.println(f.getName());}}}任務(wù)7-5獲取目錄下的所有文本文件并輸出運(yùn)行結(jié)果如圖7-5所示。想要過濾不需要的文件需要自定義過濾規(guī)則,只需要自定義一個(gè)FilenameFilter對(duì)象,并實(shí)現(xiàn)該對(duì)象的accept()方法即可。accept()方法包含兩個(gè)參數(shù),一個(gè)是文件對(duì)象,另一個(gè)是文件對(duì)象的名稱。任務(wù)對(duì)以非.dll結(jié)尾的文件進(jìn)行過濾,凡是不以此結(jié)尾的文件類型全部跳過,最后返回文件列表。任務(wù)7-6刪除文件夾文件DirDelDemo.javaimportjava.io.File;publicclassDirDelDemo{publicstaticvoidmain(String[]args){Filefile=newFile("E:/AppPatch");//創(chuàng)建file對(duì)象if(file.exists()&&file.isDirectory()){//只有文件存在并且是文件夾才進(jìn)行此操作DirDelDemodel=newDirDelDemo();System.out.println("刪除開始!");del.delFile(file);//遞歸刪除System.out.println("刪除結(jié)束!");}}//遞歸刪除文件夾publicvoiddelFile(Filefile){File[]files=file.listFiles();//獲取文件夾下的文件列表for(Filef:files){//遍歷文件列表if(f.isDirectory()){//如果是文件夾delFile(f);//遞歸刪除文件夾System.out.println("刪除文件夾;"+f.getAbsolutePath());f.delete();}else{//否則,如果是文件,則直接刪除文件System.out.println("刪除文件"+f.getAbsolutePath());f.delete();}}//如果想將該文件目錄也刪除,則可以直接調(diào)用delete()方法//因?yàn)榻?jīng)過遞歸刪除方式刪除后,該文件夾已經(jīng)是空的了file.delete();//刪除根文件夾}}運(yùn)行結(jié)果如圖7-7所示。目錄導(dǎo)航7.1

File類7.3項(xiàng)目實(shí)戰(zhàn)7.2輸入輸出流7.4單元小結(jié)7.2.1輸入輸出流的概念Java在處理標(biāo)準(zhǔn)的設(shè)備文件和普通文件時(shí)并不區(qū)分類型,而是采用“數(shù)據(jù)流”的概念來實(shí)現(xiàn)對(duì)文件系統(tǒng)的操作,所以流的性質(zhì)是完全類似的。流中存放的是有序的字符(字節(jié))序列。在操作流對(duì)象時(shí),只需要指定對(duì)應(yīng)的目標(biāo)對(duì)象,其數(shù)據(jù)讀寫操作基本一致。流式輸入輸出是一種很常見的輸入輸出方式,輸入流代表從外部設(shè)備流入計(jì)算機(jī)內(nèi)存的數(shù)據(jù)序列,輸出流則代表從計(jì)算機(jī)內(nèi)存向外部設(shè)備流出的數(shù)據(jù)序列。流中的數(shù)據(jù)因數(shù)據(jù)類型不同,可以分為兩類,一類是字節(jié)流,其頂級(jí)父類是InputStream類和OutputStream類,這種流一次讀寫8位二進(jìn)制;一類是字符流,其頂級(jí)父類是Reader類和Writer類,這種流一次讀寫16位二進(jìn)制。對(duì)于輸入輸出流,每次使用之后都需要執(zhí)行關(guān)閉操作,否則會(huì)造成系統(tǒng)資源浪費(fèi),同時(shí)可能會(huì)帶來意想不到的問題。Java提供了語法糖try-catch-resource,會(huì)在使用輸入輸出流完畢之后自動(dòng)將其關(guān)閉,不需要開發(fā)者手動(dòng)處理。7.2.1輸入輸出流的概念try-catch-resource語法糖的使用方式如下:try(BufferedReaderbr=newBufferedReader(newFileReader(file));BufferedWriterbw=newBufferedWriter(newFileWriter(file,true))){//TODO方法處理邏輯…}catch(Exceptione){//TODO異常處理…}注意:如果一個(gè)類沒有繼承Closeable類,則不能使用try-catch-resource。Java中的輸入輸出操作類繁多,大致可以分為如下4類。①

基于字節(jié)操作的輸入輸出類:InputStream和OutputStream。

基于字符操作的輸入輸出類:Reader和Writer。

基于磁盤操作的輸入輸出類:File。

基于網(wǎng)絡(luò)操作的輸入輸出類:Socket。7.2.2字節(jié)流流中的數(shù)據(jù)是按字節(jié)進(jìn)行傳輸?shù)?,所有的?shù)據(jù)流都可以使用字節(jié)流進(jìn)行讀寫操作。InputStream類是所有字節(jié)輸入流的基類,其作用是標(biāo)識(shí)不同數(shù)據(jù)源產(chǎn)生的輸入流。這些數(shù)據(jù)源包括字節(jié)數(shù)據(jù)、字符串對(duì)象、文件、管道和一些由其他流組成的序列等。OutputStream類是所有字節(jié)輸出流的基類,它定義了數(shù)據(jù)輸出的目的地。字節(jié)流本身是抽象類,派生出很多個(gè)子類,用于不同情況下的數(shù)據(jù)輸入和輸出操作,其類的繼承關(guān)系如圖所示。01OPTION概述7.2.2字節(jié)流表7-2InputStream類的常用方法方法名稱方法說明intavailable()返回流中可供讀?。ɑ蛱^)的字節(jié)數(shù)據(jù)

voidclose()關(guān)閉輸入流,釋放相關(guān)資源voidmark(intreadlimit)在輸入流中標(biāo)記當(dāng)前位置booleanmarkSupported()輸入流是否支持mark()和reset()方法abstractintread()從流中讀取一個(gè)字節(jié)的數(shù)據(jù)intread(byte[]b)從流中讀取b.length大小的數(shù)據(jù),放進(jìn)b中intread(byte[]b,intoff,intlen)讀取最多l(xiāng)en長度的數(shù)據(jù)到b中,從off指定的偏移位置開始存放voidreset()將流重置到mark()方法最后一次標(biāo)記的位置voidskip(longn)跳過并拋棄n個(gè)流中的數(shù)據(jù)7.2.2字節(jié)流任務(wù)7-7文件輸入輸出流02OPTION字節(jié)流的應(yīng)用文件StreamDemo.javaimportjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;publicclassFileStreamDemo{publicstaticvoidmain(String[]args){Filefile=newFile("FileStreamDemo.txt");//創(chuàng)建一個(gè)文件對(duì)象if(!file.exists()){try{file.createNewFile();//如果文件不存在,則創(chuàng)建文件}catch(IOExceptione){e.printStackTrace();}}/**使用語法糖,因?yàn)镕ileInputStream類和FileOutputStream類分別繼承了*InputStream類和OutputStream類,而這兩個(gè)類繼承了Closeable類,*所以此處可以使用try-with-resource方式*/try(FileInputStreamfis=newFileInputStream(file);FileOutputStreamfos=newFileOutputStream(file)){//如果FileInputStream類支持標(biāo)記,則在文件的開始設(shè)置標(biāo)記if(fis.markSupported()){fis.mark(1000);//設(shè)置標(biāo)記System.out.println("文件開始標(biāo)記設(shè)置成功!");}else{System.out.println("流對(duì)象不支持標(biāo)記設(shè)置!");}intdata=-1;System.out.println("文件輸入流讀取開始:");while(-1!=(data=fis.read())){System.out.print((char)data+"");}System.out.println("\n文件輸入流讀取結(jié)束!");7.2.2字節(jié)流StringwriteLine="Thisisthefirsttimetowrite!";fos.write(writeLine.getBytes());//在文件中寫入一行數(shù)據(jù)fos.flush();//強(qiáng)制刷新緩存的數(shù)據(jù)//再次讀取文件System.out.println("文件輸入流讀取開始:");while(-1!=(data=fis.read())){System.out.print((char)data+"");}System.out.println("\n文件輸入流讀取結(jié)束!");}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}運(yùn)行結(jié)果如圖所示。7.2.2字節(jié)流任務(wù)7-8文件的復(fù)制文件FileCopyDemo.javaimportjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;publicclassFileCopyDemo{publicstaticvoidmain(String[]args){Stringpath=FileCopyDemo.class.getResource("").toString();//獲取當(dāng)前類的所在路徑System.out.println("class文件路徑是:"+path);StringfilePath=path.substring(path.indexOf("/")+1).replace("bin","src");System.out.println("java文件路徑是:"+filePath);FilecurrFile=newFile(filePath+"FileCopyDemo.java");//獲取需要復(fù)制的源文件對(duì)象FiledestFile=newFile("CopyDemo.txt");//獲取需要將數(shù)據(jù)復(fù)制到的目標(biāo)文件對(duì)象try(FileInputStreamfis=newFileInputStream(currFile);FileOutputStreamfos=newFileOutputStream(destFile,false)){byte[]b=newbyte[2048];//需要讀取的字節(jié)數(shù)組while(-1!=fis.read(b)){//如果文件中有數(shù)據(jù),則繼續(xù)讀取fos.write(b);//將讀取到的數(shù)據(jù)寫入目標(biāo)文件}fos.flush();//刷新緩存System.out.println("文件復(fù)制結(jié)束!");}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}7.2.2字節(jié)流運(yùn)行結(jié)果如圖7-10所示。7.2.2字節(jié)流任務(wù)7-9使用RandomAccessFile類操作文件文件RandomAccessFileDemo.javapublicclassRandomAccessFileDemo{publicstaticvoidmain(String[]args){Filefile=newFile("Test.txt");//使用Test.txt文件if(!file.exists()){//如果文件不存在//調(diào)用StreamDemo的文件處理方法,確保文件中有數(shù)據(jù)StreamDemodemo=newStreamDemo();demo.streamDemo();}//使用closeable方式創(chuàng)建RandomAccessFile對(duì)象try(RandomAccessFileraf=newRandomAccessFile(file,"rw")){System.out.println("文件的長度是:"+raf.length());Stringline=null;intcount=1;while(null!=(line=raf.readLine())){//如果文件中存在數(shù)據(jù),則按行讀取System.out.println("文件中的第"+(count++)+"行數(shù)據(jù)是:"+line);}System.out.println("當(dāng)前文件的偏移位置是:"+raf.getFilePointer());

raf.seek(0);System.out.println("文件當(dāng)前偏移位置:"+raf.getFilePointer());System.out.println("當(dāng)前讀取的字符是:"+(char)(raf.readByte()));raf.seek(raf.length());raf.writeBytes("\r\n");raf.writeChars("Hello!");raf.seek(0);count=1;while(null!=(line=raf.readLine())){//如果文件中存在數(shù)據(jù),則按行讀取System.out.println("文件中的第"+(count++)+"行數(shù)據(jù)是:"+line);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}7.2.2字節(jié)流運(yùn)行結(jié)果如圖7-11所示。輸入輸出的字節(jié)流還有緩存字節(jié)流,如ufferedInputStream類和BufferedOutputStream類等。這些流對(duì)象有緩存機(jī)制,支持mark()方法和reset()方法。對(duì)于可能需要多次讀取的數(shù)據(jù),可以將字節(jié)流轉(zhuǎn)換成緩存字節(jié)流進(jìn)行處理。7.2.3字符流字節(jié)流的頂級(jí)父類是Reader類和Writer類,一個(gè)用于讀取,一個(gè)用于寫入,其對(duì)應(yīng)的輸入輸出字符流是InputStreamReader類和OutputStreamWriter類。為了方便讀取,我們可以使用BufferedReader類和BufferedWriter類,對(duì)流進(jìn)行按行讀取和寫入,其具體應(yīng)用如任務(wù)7-10所示。任務(wù)7-10使用緩存字符流讀取和寫入數(shù)據(jù)文件ReaderAndWriterDemo.javapublicclassReaderAndWriterDemo{publicstaticvoidmain(String[]args){Filefile=newFile("RW.txt");if(!file.exists()){System.out.println("不存在,創(chuàng)建新文件!");try{file.createNewFile();//不存在就創(chuàng)建一個(gè)文件}catch(IOExceptione){e.printStackTrace();}}else{System.out.println("已存在,無須創(chuàng)建!");}try(BufferedReaderbr=newBufferedReader(newFileReader(file));BufferedWriterbw=newBufferedWriter(newFileWriter(file,true))){br.mark(10000);//在流開始讀取時(shí)進(jìn)行標(biāo)記Stringline=null;intcount=1;System.out.println("開始數(shù)據(jù)讀?。?);while(null!=(line=br.readLine())){//按行讀取數(shù)據(jù)System.out.println("第"+(count++)+"行數(shù)據(jù)是:"+line);}//按行寫入數(shù)據(jù)(一行)System.out.println("\n開始數(shù)據(jù)插入!");bw.write("addnewline\r\n");bw.flush();//強(qiáng)制刷新緩存中的數(shù)據(jù)7.2.3字符流運(yùn)行結(jié)果如圖7-12所示。//再次讀取count=1;System.out.println("\n再次讀取數(shù)據(jù):");br.reset();//跳回到標(biāo)記位置while(null!=(line=br.readLine())){System.out.println("第"+(count++)+"行數(shù)據(jù)是:"+line);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}目錄導(dǎo)航7.1

File類7.3項(xiàng)目實(shí)戰(zhàn)7.2輸入輸出流7.4單元小結(jié)項(xiàng)目7-1實(shí)現(xiàn)MapReduce框架中的SplitprivateStringinputFile;privateStringoutputDir;publicInputSplit(StringinputFile,StringoutputDir){this.inputFile=inputFile;this.outputDir=outputDir;}/***生成分割后文件的文件名*/privatePathgetFilePath(intseq){returnPaths.get(outputDir,String.format("split_%d",seq));}/***方法的功能是將一個(gè)大文件按指定大小分割成若干個(gè)小文件*input:原始的大文件*outputFile:分割后的小文件*@paramblockSize分割的單位大小*/文件InputSplit.javapublicList<String>split(longblockSize){//用于存儲(chǔ)分割后的文件名List<String>files=newArrayList<>();//分割文件的序號(hào)intseq=0;try(BufferedReaderbr=Files.newBufferedReader(Paths.get(inputFile),StandardCharsets.UTF_8)){longsize=0L;Stringline;PathfilePath=getFilePath(seq);BufferedWriterbw=Files.newBufferedWriter(filePath,StandardCharsets.UTF_8);files.add(filePath.toString());bw.write(String.valueOf(seq));bw.newLine();學(xué)習(xí)文件操作之后,就可以繼續(xù)實(shí)現(xiàn)MapReduce框架中的Split階段了。Split階段的任務(wù)是接收一個(gè)輸入文件,按指定的大小將文件分割成若干個(gè)小文件,具體如下。項(xiàng)目7-1實(shí)現(xiàn)MapReduce框架中的Split

while((line=br.readLine())!=null){bw.write(line);bw.newLine();//統(tǒng)計(jì)當(dāng)前文件已經(jīng)寫入了多大的數(shù)據(jù)size+=line.getBytes(StandardCharsets.UTF_8).length;//達(dá)到分割的大小時(shí),關(guān)閉當(dāng)前文件,生成一個(gè)新的文件if(size>=blockSize){bw.close();bw.close();++seq;filePath=getFilePath(seq);bw=Files.newBufferedWriter(filePath,StandardCharsets.UTF_8);bw.write(String.valueOf(seq));bw.newLine();files.add(filePath.toString());size=0L;}}}catch(Exceptione){e.printStackTrace();}returnfiles;}}InputSplit類中首先定義了getFilePath()方法,根據(jù)序號(hào)生成分割文件的文件名,例如第0個(gè)分割文件的文件名為split_0。split()方法執(zhí)行對(duì)inputFile的具體分割操作,首先通過BufferedReader類對(duì)inputFile按行讀取,然后通過BufferedWriter類將數(shù)據(jù)寫入結(jié)果文件。在寫入的過程中不斷統(tǒng)計(jì)數(shù)據(jù)的大小,如果達(dá)到一定的大小,則寫入一個(gè)新的文件中。分割過程中產(chǎn)生的結(jié)果文件,其文件名都存儲(chǔ)在List中并返回,用于MapReduce的Map階段,以便從中讀取相應(yīng)的文件名。項(xiàng)目7-2文件系統(tǒng)下面再通過一個(gè)小項(xiàng)目來演示如何操作文件。項(xiàng)目的目標(biāo)是編寫一個(gè)簡單的文件管理系統(tǒng),通過控制臺(tái)的輸出內(nèi)容進(jìn)行文件操作:1表示創(chuàng)建文件,2表示刪除文件,3表示復(fù)制文件,4表示根據(jù)輸入文件的名稱讀取文件內(nèi)容并執(zhí)行對(duì)應(yīng)的指令。當(dāng)用戶輸入1時(shí),會(huì)讀取用戶的下一行輸入,根據(jù)用戶的名稱和后續(xù)輸入創(chuàng)建一個(gè)文件并將輸入錄入文件。當(dāng)用戶輸入2時(shí),會(huì)檢索當(dāng)前目錄下的文件,如果文件存在,則刪除該文件;否則,提示文件不存在。當(dāng)用戶輸入3時(shí),讀取用戶輸入的文件名稱并進(jìn)行復(fù)制,并在文件名稱的末尾添加.copy作為標(biāo)記。當(dāng)用戶輸入4時(shí),會(huì)查找當(dāng)前目錄下的文件。如果文件存在,則執(zhí)行文件的內(nèi)容。若用戶輸入“exit”并在系統(tǒng)詢問時(shí)輸入“Y”,則退出當(dāng)前系統(tǒng)。具體實(shí)現(xiàn)如下。文件FileSystemClient.javapackagecom.lw.demo;importjava.util.Scanner;publicclassFileSystemClient{publicstaticvoidmain(String[]args){Scannerscan=newScanner(System.in);//獲取控制臺(tái)輸入的內(nèi)容//文件處理對(duì)象初始化FileOperatorfo=newFileOperator();while(true){System.out.println("1-創(chuàng)建文件2-刪除文件3-復(fù)制文件4-執(zhí)行文件

exit-退出系統(tǒng):");switch(scan.nextLine()){case"1":fo.createFile(scan);break;項(xiàng)目7-2文件系統(tǒng)case"2":fo.delFile(scan);break;case"3":fo.copyFile(scan);break;case"4":fo.execFile(scan);break;case"exit":System.exit(0);break;default:System.out.println("未知指令!請(qǐng)輸入正確的指令:");break;}}}}文件FileOperator.javapackagecom.lw.demo;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.util.Scanner;publicclassFileOperator{publicstaticfinalStringLINE_END_TAG="\r\n";publicstaticfinalStringEND_INPUT="--END";//創(chuàng)建文件并寫入數(shù)據(jù)publicvoidcreateFile(Scannerscanner){System.out.println("請(qǐng)輸入文件名稱:");StringfileName=scanner.nextLine();//獲取文件名稱Filefile=newFile(fileName);//如果文件不存在,則創(chuàng)建文件if(!file.exists()){try{file.createNewFile();}catch(IOExceptione){e.printStackTrace();}}項(xiàng)目7-2文件系統(tǒng)System.out.println("請(qǐng)輸入想要寫入文件的內(nèi)容,以--END結(jié)束輸入:");//獲取想要寫入文件的內(nèi)容Stringline=scanner.nextLine();try(BufferedWriterbw=newBufferedWriter(newFileWriter(file))){while(true){//如果不是結(jié)束輸入的標(biāo)記,則直接結(jié)束輸入if(END_INPUT.equals(line)){return;}bw.write(line.concat(LINE_END_TAG));line=scanner.nextLine();}}catch(IOExceptione){e.printStackTrace();}System.out.println("文件創(chuàng)建成功!請(qǐng)執(zhí)行后續(xù)指令!");}//刪除文件publicvoiddelFile(Scannerscanner){System.out.println("請(qǐng)輸入想要?jiǎng)h除的文件全路徑:");StringfilePath=scanner.nextLine();Filefile=newFile(filePath);if(file.exists()&&file.isFile()){//文件存在且不是目錄,則刪除文件file.delete();System.out.println("文件刪除成功!刪除文件:"+file.getAbsolutePath());}else{System.out.println("文件不存在,無法刪除!請(qǐng)執(zhí)行后續(xù)指令!");}}//復(fù)制文件publicvoidcopyFile(Scannerscanner){System.out.println("請(qǐng)輸入想要復(fù)制的文件全路徑:");StringfilePath=scanner.nextLine();Filefile=newFile(filePath);if(!file.exists()){System.out.println("文件不存在!");return;}if(!file.isFile()){System.out.println("不是文件,無法復(fù)制!");return;}//獲取文件路徑Stringpath=filePath.substring(0,filePath.lastIndexOf("\\")+1);System.out.println("請(qǐng)輸入想要復(fù)制到的文件名稱:");Stringname=scanner.nextLine();FilenewFile=newFile(path.concat(name));if(newFile.exists()){System.out.println("目標(biāo)文件已存在,是否要覆蓋(Y/N):");Stringtag=scanner.nextLine();if("N".equals(tag)){

項(xiàng)目7-2文件系統(tǒng)System.out.println("請(qǐng)輸入想要復(fù)制到的文件名稱:");name=scanner.nextLine();newFile=newFile(path.concat(name));}}//讀取源文件內(nèi)容并寫入目標(biāo)文件中try(FileInputStreamfis=newFileInputStream(file);FileOutputStreamfos=newFileOutputStream(newFile)){byte[]buf=newbyte[1024];//讀取數(shù)據(jù)while(fis.read(buf)!=-1){fos.write(buf);//如果有內(nèi)容,則進(jìn)行文件寫入}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}System.out.println("文件復(fù)制成功!");}//讀取執(zhí)行文件,進(jìn)行非實(shí)時(shí)文件處理publicvoidexecFile(Scannerscanner){System.out.println("請(qǐng)輸入想要執(zhí)行的執(zhí)行文件:");StringfilePath=scanner.nextLine();Filefile=newFile(filePath);if(!file.exists()){System.out.println("執(zhí)行文件不存在!");return;}

if(!file.isFile()){System.out.println("不是文件,無法進(jìn)行執(zhí)行!");return;}System.out.println("開始執(zhí)行執(zhí)行文件:");//執(zhí)行執(zhí)行文件的邏輯try(BufferedReaderbr=newBufferedReader(newFileReader(file))){Stringline=br.readLine();while(null!=line&&!"".equals(line)){String[]infos=line.split("");switch(infos[0]){case"1":createFileByBatch(infos);break;case"2":delFileByBatch(infos);break;case"3":copyFileByBatch(infos);break;default:System.out.println("指令錯(cuò)誤!");break;}項(xiàng)目7-2文件系統(tǒng)line=br.readLine();//讀取下一行}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}System.out.println("結(jié)束執(zhí)行執(zhí)行文件!");}//執(zhí)行文件的文件創(chuàng)建方法publicvoidcreateFileByBatch(String[]infos){Filefile=newFile(infos[1]);//文件不存在就創(chuàng)建,否則覆蓋if(!file.exists()){try{file.createNewFile();}catch(IOExceptione){e.printStackTrace();}}//沒有默認(rèn)寫入的數(shù)據(jù)if(null==infos[2]||"".equals(infos[2])){return;}//將數(shù)據(jù)寫入創(chuàng)建的文件中try(FileOutputStreamfos=newFileOutputStream(file)){for(inti=2;i<infos.length;i++){//如果是文件結(jié)束if(END_INPUT.equals(infos[i])){System.out.println("文件創(chuàng)建內(nèi)容插入結(jié)束!創(chuàng)建成功!");return;}if(!LINE_END_TAG.equals(infos[2])){fos.write(infos[2].getBytes());fos.write("".getBytes());}else{fos.write(LINE_END_TAG.getBytes());}}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}System.out.println("創(chuàng)建文件:"+infos[1]+"成功!");}//執(zhí)行文件的文件刪除方法publicvoiddelFileByBatch(String[]infos){Filefile=newFile(infos[1]);//文件不存在就創(chuàng)建,否則覆蓋if(!file.exists()||!file.isFile()){System.out.println("文件不存在或者不是文件,無須刪除!");}else{//文件存在,則刪除文件file.delete();System.out.println("文件刪除成功!");}}項(xiàng)目7-2文件系統(tǒng)//執(zhí)行文件的文件復(fù)制方法publicvoidcopyFileByBatch(String[]infos){Filefile=newFile(infos[1]);FilenewFile=newFile(infos[2]);if(!file.exists()||!file.isFile()){System.out.println("文件不存在或者不是文件,無法復(fù)制!");return;}//復(fù)制副本文件,不存在則創(chuàng)建if(!newFile.exists()){try{newFile.createNewFile();}catch(IOExceptione){e.printStackTrace();}}//讀取目標(biāo)數(shù)據(jù),寫入副本文件try(FileOutputStreamfos=newFileOutputStream(newFile);FileInputStreamfis=newFileInputStream(file)){byte[]b=newbyte[1024];while(fis.read(b)!=-1){fos.write(b);}System.out.println("文件"+infos[1]+"復(fù)制成功,副本文件是"+infos[2]);}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}運(yùn)行結(jié)果如圖7-13所示。目錄導(dǎo)航7.1

File類7.3項(xiàng)目實(shí)戰(zhàn)7.2輸入輸出流7.4單元小結(jié)7.4單元小結(jié)本單元著重講解了文件和流。在Java中,文件的管理依靠File類,而文件的讀寫則依靠輸入輸出流。7.1節(jié)主要介紹了File類及其常用方法,想要更好地處理文件,F(xiàn)ile類是必須要掌握的。7.2節(jié)講解了輸入輸出流的概念及其類的繼承關(guān)系,同時(shí)分類介紹了字節(jié)流和字符流及其對(duì)應(yīng)的緩存流。7.3節(jié)項(xiàng)目實(shí)戰(zhàn)演示了File類的具體使用。

輸入輸出流是Java中非常重要的內(nèi)容,其使用范圍比較廣泛。例如項(xiàng)目中配置文件的讀取、XML文件的讀取和OFFICE文件的讀取等,都是使用輸入輸出流進(jìn)行的。在Java的Web實(shí)際應(yīng)用中,客戶端的瀏覽器界面與應(yīng)用服務(wù)器之間的交互同樣是依靠流的形式進(jìn)行的。第8單元日期和時(shí)間Java程序設(shè)計(jì)基礎(chǔ)教程((慕課版)(第2版))目錄導(dǎo)航8.1

Date類8.3項(xiàng)目實(shí)戰(zhàn)8.2

Calendar類8.4單元小結(jié)8.1.1計(jì)算機(jī)的時(shí)間1970年1月1日是UNIX(UniplexedInformationandComputingService,分時(shí)復(fù)用信息計(jì)算服務(wù))和C語言的生日。美國計(jì)算機(jī)科學(xué)家肯尼斯·藍(lán)·湯普遜使用B語言在PDP(ProgrammedDataProcessor,程序數(shù)據(jù)處理機(jī))-7機(jī)器上開發(fā)出了UNIX的一個(gè)新版本,隨后又與同事丹尼斯·里奇改進(jìn)了B語言,開發(fā)出了C語言并重寫了UNIX。當(dāng)時(shí),計(jì)算機(jī)系統(tǒng)是32位系統(tǒng)。時(shí)間若使用32位有符號(hào)數(shù)表示,可以表示68年;若用32位無符號(hào)數(shù)表示,可以表示136年。當(dāng)時(shí)人們認(rèn)為可以以1970年1月1日0時(shí)0分0秒為時(shí)間原點(diǎn),并在C語言的time()方法中這么應(yīng)用了。因此,計(jì)算機(jī)便使用1970年1月1日0時(shí)0分0秒作為時(shí)間原點(diǎn),隨后的語言也沿用了這種設(shè)定。任務(wù)8-1當(dāng)前時(shí)間與計(jì)算機(jī)時(shí)間原點(diǎn)文件ComputerTimeDemo.javapublicclassComputerTimeDemo{publicstaticvoidmain(String[]args)throwsParseException{Dateday=newDate(0);//獲取時(shí)間原點(diǎn)longtime=System.currentTimeMillis();//獲取當(dāng)前時(shí)間相較于時(shí)間原點(diǎn)的毫秒數(shù)Datedate=newDate(time);//獲取Date類型的對(duì)象,時(shí)間默認(rèn)為當(dāng)前時(shí)間//Date類型的toLocaleString()方法已經(jīng)被廢棄,不建議使用,但為了演示方便,暫且使用System.out.println("當(dāng)前時(shí)間:"+date.toLocaleString());System.out.println("計(jì)算機(jī)時(shí)間原點(diǎn):"+day.toLocaleString());longbetween=date.getTime()-day.getTime();System.out.println("系統(tǒng)當(dāng)前時(shí)間與計(jì)算機(jī)時(shí)間原點(diǎn)的毫秒值;"+between);System.out.println("當(dāng)前時(shí)間與時(shí)間原點(diǎn)的差值與系統(tǒng)獲取的當(dāng)前毫秒值的差值:"+(time-between));}}運(yùn)行結(jié)果如圖8-1所示。從運(yùn)行結(jié)果不難發(fā)現(xiàn),Java中的時(shí)間原點(diǎn)是1970年1月1日8時(shí)0分0秒(細(xì)心的讀者可能會(huì)問為何不是0點(diǎn),這是因?yàn)楸本┰跂|八區(qū),所以使用北京時(shí)間時(shí)默認(rèn)是8點(diǎn))。Java中獲取系統(tǒng)當(dāng)前時(shí)間毫秒值的方法是Native()方法,該方法是用C語言實(shí)現(xiàn)的。8.1.2Date類的應(yīng)用Date類的無參構(gòu)造方法通過獲取當(dāng)前系統(tǒng)的毫秒值來初始化一個(gè)日期對(duì)象,同時(shí)Date類也提供了一個(gè)接受毫秒值的構(gòu)造函數(shù)。無參構(gòu)造方法就是將系統(tǒng)當(dāng)前毫秒值傳入該構(gòu)造函數(shù),所以在任務(wù)8-1中最后的毫秒差值是0。另外,當(dāng)傳入一個(gè)0作為參數(shù)的時(shí)候,返回的是計(jì)算機(jī)時(shí)間原點(diǎn)。SimpleDateFormat類是用于時(shí)間格式化的工具類,它可將日期格式化為字符串,同時(shí)也支持將字符串轉(zhuǎn)換為日期對(duì)象的方法。任務(wù)8-2Date類的使用文件DateDemo.javapublicclassDateDemo{publicstaticvoidmain(String[]args){Datedate=newDate();//獲取計(jì)算機(jī)的當(dāng)前時(shí)間SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");//參數(shù)是日期的格式StringdateStr=sdf.format(date); //將時(shí)間格式化System.out.println("格式化輸出時(shí)間:"+dateStr);StringdayStr="1990-01-0100:00:00"; //格式化后的日期類型的字符串try{Dateday=sdf.parse(dayStr); //將字符串轉(zhuǎn)換成日期類型System.out.println("使用格式化的日期字符串創(chuàng)建的日期對(duì)象;"+day);}catch(ParseExceptione){e.printStackTrace();}}}運(yùn)行結(jié)果如圖8-2所示。Date類定義了一些簡單的初始化構(gòu)造方法,SimpleDateFormat類中定義了一些簡單的格式化方法,但是日期的使用不僅限于初始化和格式化。目錄導(dǎo)航8.1

Date類8.3項(xiàng)目實(shí)戰(zhàn)8.2

Calendar類8.4單元小結(jié)8.2.1Calendar類簡介Calendar類用于進(jìn)行日期的計(jì)算操作,其本身可以由Date類來設(shè)置需要進(jìn)行計(jì)算的時(shí)間原點(diǎn),同時(shí)能快速地轉(zhuǎn)換成Date類的對(duì)象并輸出。因?yàn)榫幊陶Z言中大多以0為初始值,所以Calendar類中的1月對(duì)應(yīng)的數(shù)字實(shí)際上是0。由于西方國家認(rèn)為星期日是一個(gè)星期的開始,所以,SUNDAY對(duì)應(yīng)的數(shù)字是1,而MONDAY對(duì)應(yīng)的數(shù)字是2,其他以此類推。8.2.2Calendar類的計(jì)算Calendar類能夠快速進(jìn)行時(shí)間的計(jì)算,如基于當(dāng)前日期計(jì)算某天之前或者之后的日期,或者計(jì)算某個(gè)月的第幾個(gè)星期幾的日期。文件CalendarDemo.javapublicclassCalendarDemo{publicstaticvoidmain(String[]args){Datedate=newDate();//當(dāng)前時(shí)間對(duì)象SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");System.out.println("當(dāng)前時(shí)間是:"+sdf.format(date));//初始化一個(gè)日歷對(duì)象Calendarcale=Calendar.getInstance();System.out.println("當(dāng)前日歷類型是:"+cale.getCalendarType());//將星期一設(shè)置為每個(gè)星期的第一天System.out.println("每個(gè)星期的第一天是:"+cale.getFirstDayOfWeek());cale.setFirstDayOfWeek(2);System.out.println("每個(gè)星期的第二天是:"+cale.getFirstDayOfWeek());cale.setTime(date);//將當(dāng)前時(shí)間設(shè)置為日歷類的初始計(jì)算時(shí)間任務(wù)8-3日期的計(jì)算8.2.2Calendar類的計(jì)算//當(dāng)前時(shí)間5天前的時(shí)間(在當(dāng)前域中加上傳入的值,正數(shù)表示之前,負(fù)數(shù)表示之后)cale.add(Calendar.DAY_OF_YEAR,-5);Dateday=cale.getTime();System.out.println("5天前的時(shí)間是:"+sdf.format(day));//獲取每個(gè)域的值System.out.println("當(dāng)前年份是:"+cale.get(Calendar.YEAR));System.out.println("當(dāng)前月份是:"+cale.get(Calendar.MONTH));System.out.println("當(dāng)前日是:"+cale.get(Calendar.DATE));//獲取各個(gè)域的最大值System.out.println("本月份的最大天數(shù):"+cale.getActualMaximum(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論