




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7單元文件及流Java程序設(shè)計基礎(chǔ)教程((慕課版)(第2版))目錄導航7.1
File類7.3項目實戰(zhàn)7.2輸入輸出流7.4單元小結(jié)7.1.1File類的常用方法表7-1File類的常用方法方法名稱方法說明File(Fileparent,Stringchild)創(chuàng)建一個File對象,該對象的路徑由parent的絕對路徑與child字符串組成,代表一個新的目錄或文件路徑File(StringpathName)創(chuàng)建一個File對象,將pathName的指定路徑轉(zhuǎn)換成絕對路徑File(URLurl)創(chuàng)建一個File對象,將URL(UniformResourceLocator,統(tǒng)一資源定位符)轉(zhuǎn)換成絕對路徑booleancanRead()判斷文件是否可讀booleancanWrite()判斷文件是否可寫booleancreateNewFile()創(chuàng)建一個文件或目錄booleandelete()刪除一個文件booleanexist()判斷文件是否存在StringgetName()獲取文件或目錄的名字booleanisDirectory()判斷當前對象是否是目錄booleanisFile()判斷當前對象是否是文件booleanisHidden()判斷文件是否是隱藏文件longlastModified()文件最后一次修改時間longlength()返回文件的長度String[]list()返回當前對象所代表的目錄下的所有文件和目錄列表File[]listFiles()返回當前對象所代表的目錄下的所有文件列表File[]listFiles(FileFilterfilter)返回當前對象所代表的目錄下的文件列表,要求符合過濾規(guī)則booleanmkdir()創(chuàng)建目錄booleanrenameTo(Filedest)將文件改名成dest對象所指示的名字booleansetLastModified(longtime)設(shè)置文件或目錄的最后修改時間booleansetReadOnly()將文件或目錄設(shè)置成可讀7.1.1File類的常用方法下面通過任務(wù)7-1來了解創(chuàng)建與刪除文件的操作。01OPTION文件的創(chuàng)建與刪除為了獲取文件的固有屬性,例如文件的路徑、內(nèi)容長度和是否隱藏等,可在項目路徑下創(chuàng)建一個.txt文件,名稱是InherenetAttributeTest;然后在里面寫一些內(nèi)容,如“Thisfileisthetestforfile'sinherentattribute.”,讓getlength()方法不返回0。
下面通過任務(wù)7-2了解如何獲取文件的固有屬性。文件的固有屬性02OPTION文件的可變屬性03OPTION文件的有些屬性是可以被修改的,這些內(nèi)容包含文件的可讀性、可寫性和最后修改時間等。
下面通過任務(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)建一個文件類型對象Filedir=newFile("\\creatDir");System.out.println("文件是否存在:"+file.exists());System.out.println("文件夾是否存在:"+dir.exists());if(!file.exists()){try{file.createNewFile();//如果文件不存在,則創(chuàng)建一個新的文件}catch(IOExceptione){e.printStackTrace();}}if(!dir.exists()){dir.mkdir();//如果文件夾不存在,則創(chuàng)建一個文件夾}System.out.println("文件是否存在:"+file.exists());System.out.println("文件夾是否存在:"+dir.exists());System.out.println("文件的絕對路徑是:"+file.getAbsolutePath());System.out.println("文件夾的絕對路徑是:"+dir.getAbsolutePath());file.delete();//刪除文件System.out.println("文件是否存在:"+file.exists());}}運行結(jié)果如圖7-1所示。文件對象是通過newFile("文件路徑")的方式創(chuàng)建的,但是創(chuàng)建之前虛擬機不知道這個文件是否存在。文件是否存在是使用File類的exists()方法來判斷的。如果文件不存在,可以使用createNewFile()方法創(chuàng)建一個這樣的文件。如果文件存在,但這個文件是一個文件夾而非一個文件,如果將此以文件類型而非文件夾類型進行處理,也會拋出文件找不到的異常。文件的刪除比較簡單,直接調(diào)用File對象的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("文件的絕對路徑:"+file.getAbsolutePath());System.out.println("文件的相對路徑:"+file.getPath());System.out.println("文件是否是隱藏文件:"+file.isHidden());System.out.println("是否是文件類型:"+file.isFile());System.out.println("是否是文件夾類型:"+file.isDirectory());}}}運行結(jié)果如圖7-2所示。任務(wù)7-3獲取文件的可變屬性文件FileVariableAttributeDemo.javaimportjava.io.File;publicclassFileVariableAttributeDemo{publicstaticvoidmain(String[]args){Filefile=newFile("InherenetAttributeTest.txt");//創(chuàng)建文件對象if(file.exists()){//判斷文件是否存在System.out.println("文件是否可讀:"+file.canRead());System.out.println("文件是否可寫:"+file.canWrite());System.out.println("文件上一次修改的時間(系統(tǒng)當前毫秒值):"+file.lastModified());file.setReadable(!file.canRead());//設(shè)置文件是否可讀file.setWritable(!file.canWrite());//設(shè)置文件是否可寫file.setLastModified(0);//設(shè)置文件的最后修改時間(毫秒值)System.out.println("文件是否可讀:"+file.canRead());System.out.println("文件是否可寫:"+file.canWrite());System.out.println("文件上一次修改的時間(系統(tǒng)當前毫秒值):"+file.lastModified());}}}運行結(jié)果如圖7-3所示。Java中的文件包含文件夾,所以有時候要判斷一個路徑是指向一個普通文件還是一個文件夾。如果把一個文件夾當作文件去處理,會引發(fā)FileNotFoundException異常。這個異常并非是因為該文件不存在,也可能是誤把文件夾當成文件處理了。7.1.2目錄文件遍歷下面通過任務(wù)7-4了解如何獲取子文件列表和目錄。01OPTION獲取子文件列表和目錄下面通過任務(wù)7-5了解如何獲取目錄下的所有文本文件并輸出。獲取目錄下的所有文本文件并輸出02OPTION刪除文件夾03OPTION文件夾的刪除需要使用到遞歸的思想,即如果是文件夾,就一直遞歸,直到碰到空文件夾或者只有文件的文件夾。為了便于演示,我們首先選擇一個需要刪除的文件夾,然后將此文件夾復(fù)制到另一個位置,再進行刪除,直到剩下一個空文件夾為止。為了便于操作,筆者將C盤下C:\Windows\AppPatch文件夾復(fù)制到E盤根目錄下,具體信息如圖所示。目錄文件也是文件夾,文件夾中會有子文件夾和子文件,子文件夾中有可能也有子文件或者子文件夾,所以對一個文件夾的遍歷應(yīng)當是一個遞歸的過程。如果只對一個文件夾下的所有文件夾和文件進行遍歷則比較簡單。任務(wù)7-4獲取子文件列表和目錄文件IteratorFilesDemo.javaimportjava.io.File;publicclassIteratorFilesDemo{publicstaticvoidmain(String[]args){Filefile=newFile("C:\\Users");//獲取Users目錄對象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());}}}}}運行結(jié)果如圖7-4所示。如果只是單純獲取子文件的名稱,使用list()方法即可。該方法可以獲取子文件的名稱列表,包含子文件和子文件夾,返回的是一個字符串數(shù)組,在簡單遍歷時比較方便。如果需要對子文件進行處理,則使用listFiles()方法更加有效。listFiles()方法還支持過濾,讀者可以給定過濾規(guī)則,過濾掉不需要的文件對象。任務(wù)7-5獲取目錄下的所有文本文件并輸出文件FilterFileDemo.javaimportjava.io.File;importjava.io.FilenameFilter;publicclassFilterFileDemo{publicstaticvoidmain(String[]args){Filefile=newFile("C:/ProgramFiles/Intel/MediaSDK");//自定義一個文件過濾器,用于篩選以.dll結(jié)尾的文件FilenameFilterfilter=newFilenameFilter(){@Overridepublicbooleanaccept(Filedir,Stringname){FilecurFile=newFile(dir,name);//只有文件真實存在且以.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獲取目錄下的所有文本文件并輸出運行結(jié)果如圖7-5所示。想要過濾不需要的文件需要自定義過濾規(guī)則,只需要自定義一個FilenameFilter對象,并實現(xiàn)該對象的accept()方法即可。accept()方法包含兩個參數(shù),一個是文件對象,另一個是文件對象的名稱。任務(wù)對以非.dll結(jié)尾的文件進行過濾,凡是不以此結(jié)尾的文件類型全部跳過,最后返回文件列表。任務(wù)7-6刪除文件夾文件DirDelDemo.javaimportjava.io.File;publicclassDirDelDemo{publicstaticvoidmain(String[]args){Filefile=newFile("E:/AppPatch");//創(chuàng)建file對象if(file.exists()&&file.isDirectory()){//只有文件存在并且是文件夾才進行此操作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()方法//因為經(jīng)過遞歸刪除方式刪除后,該文件夾已經(jīng)是空的了file.delete();//刪除根文件夾}}運行結(jié)果如圖7-7所示。目錄導航7.1
File類7.3項目實戰(zhàn)7.2輸入輸出流7.4單元小結(jié)7.2.1輸入輸出流的概念Java在處理標準的設(shè)備文件和普通文件時并不區(qū)分類型,而是采用“數(shù)據(jù)流”的概念來實現(xiàn)對文件系統(tǒng)的操作,所以流的性質(zhì)是完全類似的。流中存放的是有序的字符(字節(jié))序列。在操作流對象時,只需要指定對應(yīng)的目標對象,其數(shù)據(jù)讀寫操作基本一致。流式輸入輸出是一種很常見的輸入輸出方式,輸入流代表從外部設(shè)備流入計算機內(nèi)存的數(shù)據(jù)序列,輸出流則代表從計算機內(nèi)存向外部設(shè)備流出的數(shù)據(jù)序列。流中的數(shù)據(jù)因數(shù)據(jù)類型不同,可以分為兩類,一類是字節(jié)流,其頂級父類是InputStream類和OutputStream類,這種流一次讀寫8位二進制;一類是字符流,其頂級父類是Reader類和Writer類,這種流一次讀寫16位二進制。對于輸入輸出流,每次使用之后都需要執(zhí)行關(guān)閉操作,否則會造成系統(tǒng)資源浪費,同時可能會帶來意想不到的問題。Java提供了語法糖try-catch-resource,會在使用輸入輸出流完畢之后自動將其關(guān)閉,不需要開發(fā)者手動處理。7.2.1輸入輸出流的概念try-catch-resource語法糖的使用方式如下:try(BufferedReaderbr=newBufferedReader(newFileReader(file));BufferedWriterbw=newBufferedWriter(newFileWriter(file,true))){//TODO方法處理邏輯…}catch(Exceptione){//TODO異常處理…}注意:如果一個類沒有繼承Closeable類,則不能使用try-catch-resource。Java中的輸入輸出操作類繁多,大致可以分為如下4類。①
基于字節(jié)操作的輸入輸出類:InputStream和OutputStream。
②
基于字符操作的輸入輸出類:Reader和Writer。
③
基于磁盤操作的輸入輸出類:File。
④
基于網(wǎng)絡(luò)操作的輸入輸出類:Socket。7.2.2字節(jié)流流中的數(shù)據(jù)是按字節(jié)進行傳輸?shù)?,所有的?shù)據(jù)流都可以使用字節(jié)流進行讀寫操作。InputStream類是所有字節(jié)輸入流的基類,其作用是標識不同數(shù)據(jù)源產(chǎn)生的輸入流。這些數(shù)據(jù)源包括字節(jié)數(shù)據(jù)、字符串對象、文件、管道和一些由其他流組成的序列等。OutputStream類是所有字節(jié)輸出流的基類,它定義了數(shù)據(jù)輸出的目的地。字節(jié)流本身是抽象類,派生出很多個子類,用于不同情況下的數(shù)據(jù)輸入和輸出操作,其類的繼承關(guān)系如圖所示。01OPTION概述7.2.2字節(jié)流表7-2InputStream類的常用方法方法名稱方法說明intavailable()返回流中可供讀取(或跳過)的字節(jié)數(shù)據(jù)
voidclose()關(guān)閉輸入流,釋放相關(guān)資源voidmark(intreadlimit)在輸入流中標記當前位置booleanmarkSupported()輸入流是否支持mark()和reset()方法abstractintread()從流中讀取一個字節(jié)的數(shù)據(jù)intread(byte[]b)從流中讀取b.length大小的數(shù)據(jù),放進b中intread(byte[]b,intoff,intlen)讀取最多l(xiāng)en長度的數(shù)據(jù)到b中,從off指定的偏移位置開始存放voidreset()將流重置到mark()方法最后一次標記的位置voidskip(longn)跳過并拋棄n個流中的數(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)建一個文件對象if(!file.exists()){try{file.createNewFile();//如果文件不存在,則創(chuàng)建文件}catch(IOExceptione){e.printStackTrace();}}/**使用語法糖,因為FileInputStream類和FileOutputStream類分別繼承了*InputStream類和OutputStream類,而這兩個類繼承了Closeable類,*所以此處可以使用try-with-resource方式*/try(FileInputStreamfis=newFileInputStream(file);FileOutputStreamfos=newFileOutputStream(file)){//如果FileInputStream類支持標記,則在文件的開始設(shè)置標記if(fis.markSupported()){fis.mark(1000);//設(shè)置標記System.out.println("文件開始標記設(shè)置成功!");}else{System.out.println("流對象不支持標記設(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();//強制刷新緩存的數(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();}}}運行結(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();//獲取當前類的所在路徑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ù)制的源文件對象FiledestFile=newFile("CopyDemo.txt");//獲取需要將數(shù)據(jù)復(fù)制到的目標文件對象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ù)寫入目標文件}fos.flush();//刷新緩存System.out.println("文件復(fù)制結(jié)束!");}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}7.2.2字節(jié)流運行結(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對象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("當前文件的偏移位置是:"+raf.getFilePointer());
raf.seek(0);System.out.println("文件當前偏移位置:"+raf.getFilePointer());System.out.println("當前讀取的字符是:"+(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é)流運行結(jié)果如圖7-11所示。輸入輸出的字節(jié)流還有緩存字節(jié)流,如ufferedInputStream類和BufferedOutputStream類等。這些流對象有緩存機制,支持mark()方法和reset()方法。對于可能需要多次讀取的數(shù)據(jù),可以將字節(jié)流轉(zhuǎn)換成緩存字節(jié)流進行處理。7.2.3字符流字節(jié)流的頂級父類是Reader類和Writer類,一個用于讀取,一個用于寫入,其對應(yīng)的輸入輸出字符流是InputStreamReader類和OutputStreamWriter類。為了方便讀取,我們可以使用BufferedReader類和BufferedWriter類,對流進行按行讀取和寫入,其具體應(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)建一個文件}catch(IOExceptione){e.printStackTrace();}}else{System.out.println("已存在,無須創(chuàng)建!");}try(BufferedReaderbr=newBufferedReader(newFileReader(file));BufferedWriterbw=newBufferedWriter(newFileWriter(file,true))){br.mark(10000);//在流開始讀取時進行標記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();//強制刷新緩存中的數(shù)據(jù)7.2.3字符流運行結(jié)果如圖7-12所示。//再次讀取count=1;System.out.println("\n再次讀取數(shù)據(jù):");br.reset();//跳回到標記位置while(null!=(line=br.readLine())){System.out.println("第"+(count++)+"行數(shù)據(jù)是:"+line);}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}目錄導航7.1
File類7.3項目實戰(zhàn)7.2輸入輸出流7.4單元小結(jié)項目7-1實現(xiàn)MapReduce框架中的SplitprivateStringinputFile;privateStringoutputDir;publicInputSplit(StringinputFile,StringoutputDir){this.inputFile=inputFile;this.outputDir=outputDir;}/***生成分割后文件的文件名*/privatePathgetFilePath(intseq){returnPaths.get(outputDir,String.format("split_%d",seq));}/***方法的功能是將一個大文件按指定大小分割成若干個小文件*input:原始的大文件*outputFile:分割后的小文件*@paramblockSize分割的單位大小*/文件InputSplit.javapublicList<String>split(longblockSize){//用于存儲分割后的文件名List<String>files=newArrayList<>();//分割文件的序號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();學習文件操作之后,就可以繼續(xù)實現(xiàn)MapReduce框架中的Split階段了。Split階段的任務(wù)是接收一個輸入文件,按指定的大小將文件分割成若干個小文件,具體如下。項目7-1實現(xiàn)MapReduce框架中的Split
while((line=br.readLine())!=null){bw.write(line);bw.newLine();//統(tǒng)計當前文件已經(jīng)寫入了多大的數(shù)據(jù)size+=line.getBytes(StandardCharsets.UTF_8).length;//達到分割的大小時,關(guān)閉當前文件,生成一個新的文件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ù)序號生成分割文件的文件名,例如第0個分割文件的文件名為split_0。split()方法執(zhí)行對inputFile的具體分割操作,首先通過BufferedReader類對inputFile按行讀取,然后通過BufferedWriter類將數(shù)據(jù)寫入結(jié)果文件。在寫入的過程中不斷統(tǒng)計數(shù)據(jù)的大小,如果達到一定的大小,則寫入一個新的文件中。分割過程中產(chǎn)生的結(jié)果文件,其文件名都存儲在List中并返回,用于MapReduce的Map階段,以便從中讀取相應(yīng)的文件名。項目7-2文件系統(tǒng)下面再通過一個小項目來演示如何操作文件。項目的目標是編寫一個簡單的文件管理系統(tǒng),通過控制臺的輸出內(nèi)容進行文件操作:1表示創(chuàng)建文件,2表示刪除文件,3表示復(fù)制文件,4表示根據(jù)輸入文件的名稱讀取文件內(nèi)容并執(zhí)行對應(yīng)的指令。當用戶輸入1時,會讀取用戶的下一行輸入,根據(jù)用戶的名稱和后續(xù)輸入創(chuàng)建一個文件并將輸入錄入文件。當用戶輸入2時,會檢索當前目錄下的文件,如果文件存在,則刪除該文件;否則,提示文件不存在。當用戶輸入3時,讀取用戶輸入的文件名稱并進行復(fù)制,并在文件名稱的末尾添加.copy作為標記。當用戶輸入4時,會查找當前目錄下的文件。如果文件存在,則執(zhí)行文件的內(nèi)容。若用戶輸入“exit”并在系統(tǒng)詢問時輸入“Y”,則退出當前系統(tǒng)。具體實現(xiàn)如下。文件FileSystemClient.javapackagecom.lw.demo;importjava.util.Scanner;publicclassFileSystemClient{publicstaticvoidmain(String[]args){Scannerscan=newScanner(System.in);//獲取控制臺輸入的內(nèi)容//文件處理對象初始化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;項目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("未知指令!請輸入正確的指令:");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("請輸入文件名稱:");StringfileName=scanner.nextLine();//獲取文件名稱Filefile=newFile(fileName);//如果文件不存在,則創(chuàng)建文件if(!file.exists()){try{file.createNewFile();}catch(IOExceptione){e.printStackTrace();}}項目7-2文件系統(tǒng)System.out.println("請輸入想要寫入文件的內(nèi)容,以--END結(jié)束輸入:");//獲取想要寫入文件的內(nèi)容Stringline=scanner.nextLine();try(BufferedWriterbw=newBufferedWriter(newFileWriter(file))){while(true){//如果不是結(jié)束輸入的標記,則直接結(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)建成功!請執(zhí)行后續(xù)指令!");}//刪除文件publicvoiddelFile(Scannerscanner){System.out.println("請輸入想要刪除的文件全路徑:");StringfilePath=scanner.nextLine();Filefile=newFile(filePath);if(file.exists()&&file.isFile()){//文件存在且不是目錄,則刪除文件file.delete();System.out.println("文件刪除成功!刪除文件:"+file.getAbsolutePath());}else{System.out.println("文件不存在,無法刪除!請執(zhí)行后續(xù)指令!");}}//復(fù)制文件publicvoidcopyFile(Scannerscanner){System.out.println("請輸入想要復(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("請輸入想要復(fù)制到的文件名稱:");Stringname=scanner.nextLine();FilenewFile=newFile(path.concat(name));if(newFile.exists()){System.out.println("目標文件已存在,是否要覆蓋(Y/N):");Stringtag=scanner.nextLine();if("N".equals(tag)){
項目7-2文件系統(tǒng)System.out.println("請輸入想要復(fù)制到的文件名稱:");name=scanner.nextLine();newFile=newFile(path.concat(name));}}//讀取源文件內(nèi)容并寫入目標文件中try(FileInputStreamfis=newFileInputStream(file);FileOutputStreamfos=newFileOutputStream(newFile)){byte[]buf=newbyte[1024];//讀取數(shù)據(jù)while(fis.read(buf)!=-1){fos.write(buf);//如果有內(nèi)容,則進行文件寫入}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}System.out.println("文件復(fù)制成功!");}//讀取執(zhí)行文件,進行非實時文件處理publicvoidexecFile(Scannerscanner){System.out.println("請輸入想要執(zhí)行的執(zhí)行文件:");StringfilePath=scanner.nextLine();Filefile=newFile(filePath);if(!file.exists()){System.out.println("執(zhí)行文件不存在!");return;}
if(!file.isFile()){System.out.println("不是文件,無法進行執(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("指令錯誤!");break;}項目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();}}//沒有默認寫入的數(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("文件刪除成功!");}}項目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();}}//讀取目標數(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();}}}運行結(jié)果如圖7-13所示。目錄導航7.1
File類7.3項目實戰(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)系,同時分類介紹了字節(jié)流和字符流及其對應(yīng)的緩存流。7.3節(jié)項目實戰(zhàn)演示了File類的具體使用。
輸入輸出流是Java中非常重要的內(nèi)容,其使用范圍比較廣泛。例如項目中配置文件的讀取、XML文件的讀取和OFFICE文件的讀取等,都是使用輸入輸出流進行的。在Java的Web實際應(yīng)用中,客戶端的瀏覽器界面與應(yīng)用服務(wù)器之間的交互同樣是依靠流的形式進行的。第8單元日期和時間Java程序設(shè)計基礎(chǔ)教程((慕課版)(第2版))目錄導航8.1
Date類8.3項目實戰(zhàn)8.2
Calendar類8.4單元小結(jié)8.1.1計算機的時間1970年1月1日是UNIX(UniplexedInformationandComputingService,分時復(fù)用信息計算服務(wù))和C語言的生日。美國計算機科學家肯尼斯·藍·湯普遜使用B語言在PDP(ProgrammedDataProcessor,程序數(shù)據(jù)處理機)-7機器上開發(fā)出了UNIX的一個新版本,隨后又與同事丹尼斯·里奇改進了B語言,開發(fā)出了C語言并重寫了UNIX。當時,計算機系統(tǒng)是32位系統(tǒng)。時間若使用32位有符號數(shù)表示,可以表示68年;若用32位無符號數(shù)表示,可以表示136年。當時人們認為可以以1970年1月1日0時0分0秒為時間原點,并在C語言的time()方法中這么應(yīng)用了。因此,計算機便使用1970年1月1日0時0分0秒作為時間原點,隨后的語言也沿用了這種設(shè)定。任務(wù)8-1當前時間與計算機時間原點文件ComputerTimeDemo.javapublicclassComputerTimeDemo{publicstaticvoidmain(String[]args)throwsParseException{Dateday=newDate(0);//獲取時間原點longtime=System.currentTimeMillis();//獲取當前時間相較于時間原點的毫秒數(shù)Datedate=newDate(time);//獲取Date類型的對象,時間默認為當前時間//Date類型的toLocaleString()方法已經(jīng)被廢棄,不建議使用,但為了演示方便,暫且使用System.out.println("當前時間:"+date.toLocaleString());System.out.println("計算機時間原點:"+day.toLocaleString());longbetween=date.getTime()-day.getTime();System.out.println("系統(tǒng)當前時間與計算機時間原點的毫秒值;"+between);System.out.println("當前時間與時間原點的差值與系統(tǒng)獲取的當前毫秒值的差值:"+(time-between));}}運行結(jié)果如圖8-1所示。從運行結(jié)果不難發(fā)現(xiàn),Java中的時間原點是1970年1月1日8時0分0秒(細心的讀者可能會問為何不是0點,這是因為北京在東八區(qū),所以使用北京時間時默認是8點)。Java中獲取系統(tǒng)當前時間毫秒值的方法是Native()方法,該方法是用C語言實現(xiàn)的。8.1.2Date類的應(yīng)用Date類的無參構(gòu)造方法通過獲取當前系統(tǒng)的毫秒值來初始化一個日期對象,同時Date類也提供了一個接受毫秒值的構(gòu)造函數(shù)。無參構(gòu)造方法就是將系統(tǒng)當前毫秒值傳入該構(gòu)造函數(shù),所以在任務(wù)8-1中最后的毫秒差值是0。另外,當傳入一個0作為參數(shù)的時候,返回的是計算機時間原點。SimpleDateFormat類是用于時間格式化的工具類,它可將日期格式化為字符串,同時也支持將字符串轉(zhuǎn)換為日期對象的方法。任務(wù)8-2Date類的使用文件DateDemo.javapublicclassDateDemo{publicstaticvoidmain(String[]args){Datedate=newDate();//獲取計算機的當前時間SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");//參數(shù)是日期的格式StringdateStr=sdf.format(date); //將時間格式化System.out.println("格式化輸出時間:"+dateStr);StringdayStr="1990-01-0100:00:00"; //格式化后的日期類型的字符串try{Dateday=sdf.parse(dayStr); //將字符串轉(zhuǎn)換成日期類型System.out.println("使用格式化的日期字符串創(chuàng)建的日期對象;"+day);}catch(ParseExceptione){e.printStackTrace();}}}運行結(jié)果如圖8-2所示。Date類定義了一些簡單的初始化構(gòu)造方法,SimpleDateFormat類中定義了一些簡單的格式化方法,但是日期的使用不僅限于初始化和格式化。目錄導航8.1
Date類8.3項目實戰(zhàn)8.2
Calendar類8.4單元小結(jié)8.2.1Calendar類簡介Calendar類用于進行日期的計算操作,其本身可以由Date類來設(shè)置需要進行計算的時間原點,同時能快速地轉(zhuǎn)換成Date類的對象并輸出。因為編程語言中大多以0為初始值,所以Calendar類中的1月對應(yīng)的數(shù)字實際上是0。由于西方國家認為星期日是一個星期的開始,所以,SUNDAY對應(yīng)的數(shù)字是1,而MONDAY對應(yīng)的數(shù)字是2,其他以此類推。8.2.2Calendar類的計算Calendar類能夠快速進行時間的計算,如基于當前日期計算某天之前或者之后的日期,或者計算某個月的第幾個星期幾的日期。文件CalendarDemo.javapublicclassCalendarDemo{publicstaticvoidmain(String[]args){Datedate=newDate();//當前時間對象SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");System.out.println("當前時間是:"+sdf.format(date));//初始化一個日歷對象Calendarcale=Calendar.getInstance();System.out.println("當前日歷類型是:"+cale.getCalendarType());//將星期一設(shè)置為每個星期的第一天System.out.println("每個星期的第一天是:"+cale.getFirstDayOfWeek());cale.setFirstDayOfWeek(2);System.out.println("每個星期的第二天是:"+cale.getFirstDayOfWeek());cale.setTime(date);//將當前時間設(shè)置為日歷類的初始計算時間任務(wù)8-3日期的計算8.2.2Calendar類的計算//當前時間5天前的時間(在當前域中加上傳入的值,正數(shù)表示之前,負數(shù)表示之后)cale.add(Calendar.DAY_OF_YEAR,-5);Dateday=cale.getTime();System.out.println("5天前的時間是:"+sdf.format(day));//獲取每個域的值System.out.println("當前年份是:"+cale.get(Calendar.YEAR));System.out.println("當前月份是:"+cale.get(Calendar.MONTH));System.out.println("當前日是:"+cale.get(Calendar.DATE));//獲取各個域的最大值System.out.println("本月份的最大天數(shù):"+cale.getActualMaximum(
溫馨提示
- 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)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T/CMES 02002-2024鋁及鋁合金焊絲產(chǎn)品質(zhì)量等級評價規(guī)范
- T/CEMIA 040-202499氧化鋁陶瓷用造粒粉
- T/CSPSTC 133-2024地鐵隧道毛細管換熱系統(tǒng)技術(shù)規(guī)程
- T/CMA JY-122-2024燃油加油機檢測安全操作規(guī)范
- 上海社區(qū)考試真題及答案
- 制作大豆農(nóng)田轉(zhuǎn)讓合同8篇
- 借款合同(附擔保條款)5篇
- 【課件】氧氣-2024-2025學年九年級化學人教版(2024)上冊
- 基礎(chǔ)建設(shè)工程儲備設(shè)備貸款合同7篇
- 辦公室衛(wèi)生評比
- 報修申請表(完整版)
- MOOC 財務(wù)報表分析-華中科技大學 中國大學慕課答案
- 師帶徒培養(yǎng)方案范文
- 山東萊陽核電項目一期工程水土保持方案
- 臨床醫(yī)學概論課程的婦產(chǎn)科學與生殖醫(yī)學
- 2024年中國鐵路物資西安有限公司招聘筆試參考題庫含答案解析
- PDCA降低護士針刺傷發(fā)生率
- 幼兒園大班美術(shù)《臉部彩繪》
- 2021年安全生產(chǎn)月:安全執(zhí)行力培養(yǎng)專題培訓課件
- 陜西碑刻總目提要編纂凡例
- GB/T 3785.1-2023電聲學聲級計第1部分:規(guī)范
評論
0/150
提交評論