




版權(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)建方法pub
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 嵌入式設(shè)備調(diào)試方法試題及答案
- 網(wǎng)絡(luò)云計(jì)算技術(shù)測驗(yàn)題及答案
- 數(shù)據(jù)庫開發(fā)中的協(xié)作工具與資源管理試題及答案
- 行政組織理論中的協(xié)同效應(yīng)分析試題及答案
- 公路工程考試面臨的知識(shí)更新挑戰(zhàn)試題及答案
- 突破2025年軟件測試工程師考試難度試題及答案
- 行政組織考試的系統(tǒng)化試題及答案
- 行政組織考試的備考指南試題及答案
- 專項(xiàng)公路工程復(fù)習(xí)試題及答案
- 整體把握的信息系統(tǒng)監(jiān)理師考試試題及答案
- 物業(yè)管理部組織架構(gòu)與職責(zé)劃分
- (2025春新版本)部編版七年級(jí)語文下冊(cè)全冊(cè)教案
- GB/T 18282.1-2025醫(yī)療保健產(chǎn)品滅菌化學(xué)指示物第1部分:通則
- 華為質(zhì)量管理手冊(cè)
- 高級(jí)病理學(xué)與病理學(xué)實(shí)驗(yàn)技術(shù)知到智慧樹章節(jié)測試課后答案2024年秋浙江中醫(yī)藥大學(xué)
- 多元藝術(shù)融合創(chuàng)造性舞蹈知到智慧樹章節(jié)測試課后答案2024年秋南京藝術(shù)學(xué)院
- 設(shè)備維護(hù)中的難題和重點(diǎn):分析與應(yīng)對(duì)計(jì)劃
- 貨運(yùn)物流提前報(bào)備通知函
- 2025年度山西建設(shè)投資集團(tuán)限公司高校畢業(yè)生招聘885人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2021-2022年北京市大興區(qū)六年級(jí)下冊(cè)期末數(shù)學(xué)試卷及答案(人教版)
- 高考高中物理知識(shí)點(diǎn)考點(diǎn)框架圖導(dǎo)圖
評(píng)論
0/150
提交評(píng)論