201621123031 《Java程序設計》第12周學習總結

做業12-流與文件


1.本週學習總結

1.1 以你喜歡的方式(思惟導圖或其餘)概括總結多流與文件相關內容。

在Java中的java.io包中定義了許多類專門負責處理各類方式的輸入與輸出。其中,全部輸入流類都是抽象類InputStream(字節輸入流)或抽象類Reader(字符輸入流)的子類,而全部輸出流類都是抽象類OutputStream(字節輸出流)或抽象類Writer(字符輸出流)的子類。
java

1.輸入流

InputStream類的層次結構

Reader類的層次結構
正則表達式

2.輸出流

OutputStream類的層次結構

Writer類的層次結構
編程

3.File類

File類是java.io包中惟一表明磁盤文件自己的對象。File類定義了一些與平臺無關的方法來操做文件,能夠經過調用File類中的方法,實現建立、刪除、重命名文件等操做。File類的對象主要用來獲取文件自己的一些信息,如文件所在的目錄、文件的長度、文件讀寫權限等。數據流能夠將數據寫入到文件中,文件也是數據流最經常使用的的數據媒體。網絡

1.文件的建立
(1).New File(String pathname)
該構造方法經過將給定路徑名字符串轉換爲抽象路徑名來建立一個新的File實例
(2).new File(String parent,String child)
該構造方法根據定義的父路徑和子路徑字符串建立一個新的File對象
(3).new File(File f,String child)
該構造方法根據parent抽象路徑名和child路徑字符串建立一個新的File實例
2.獲取文件信息
File類的經常使用方法dom

方法 返回值 說明
getName() String 獲取文件的名稱
canRead() boolean 判斷文件是不是可讀的
canWrite() boolean 判斷文件是否可被寫入
exits() boolean 判斷文件是否存在
length() long 獲取文件長度
getAbsoultePath() String 獲取文件的絕對路徑
getParent() String 獲取文件的父路徑
isFile() boolean 判斷文件是否存在
isDirectory() boolean 判斷文件是不是一個目錄
isHidden() boolean 判斷文件是不是隱藏文件
lastModified() long 獲取文件最後修改時間

2.面向系統綜合設計-圖書館管理系統或購物車

使用流與文件改造你的圖書館管理系統或購物車。編輯器

2.1 簡述如何使用流與文件改造你的系統。文件中數據的格式如何?

答:我在剛開始的時候先經過靜態初始化塊初始圖書館的數據而後將初始化後的圖書數據使用對象流ObjectOutputStream寫入文件Book.data進行保存,用戶模塊相似,而後在兩個模塊中各寫一個保存修改後文件數據的方法用於存儲操做過程當中數據變化後的文件。用對象流寫入文件是以十六進制保存的,由於對象流原本就是適合於網絡之間的傳輸。函數

2.2 簡述系統中文件讀寫部分使用了流與文件相關的什麼接口與類?爲何要用這些接口與類?

用到了InputStreamOutputStream接口下的ObjectInputStreamObjectOutputStream子類,還有文件類File,在對對象進行序列化的時候還用到了Serializable接口,使用對象流是爲了能夠將一個對象的完整信息都存入文件,若是隻是普通的字節字符流則沒辦法作到這點,而後使用對象流寫入或讀取對象時,要保證對象時序列化的,這是爲了保證能把對象寫入文件,而且從文件中正確讀到程序中,這時候就要用到Serializable接口來實現對象的序列化。工具

2.3 截圖讀寫文件相關代碼。關鍵行須要加註釋。

初始化Library:


保存修改後的Library文件:

初始化用戶模塊:

保存修改事後的用戶信息保存到文件中:
性能

選作:3. 嘗試爲計算機學院網站設計一個搜索引擎系統(組隊完成)

一開始能夠只用控制檯,不必定要用Web。學習

3.1 系統大概分爲幾部分,每一個部分要完成什麼功能?

3.2 系統的整個工做流程是什麼。各個部分之間的關係是什麼。可嘗畫圖描述。

3.3 爲了完成該系統須要什麼方面的知識?

3.代碼量統計

3.1 統計本週完成的代碼量

須要將每週的代碼統計狀況融合到一張表中。
彷佛達到了第一週設置的目標(◦˙▽˙◦)

周次 總代碼量 新增代碼量 總文件數 新增文件數
2 607 607 15 15
3 1642 1035 33 18
5 2044 402 42 9
6 2874 830 57 15
7 3161 287 63 6
8 4299 1138 72 9
9 4831 532 81 9
10 5475 644 93 12
11 5958 483 102 9
12 6819 861 116 14
13 7408 589 127 11

選作:4. 流與文件學習指導(底下的做業內容所有都是選作)

1. 字符流與文本文件:使用 PrintWriter(寫),BufferedReader(讀)

將Student對象(屬性:int id, String name,int age,double grade)寫入文件student.data、從文件讀出顯示。

1.1 生成的三個學生對象,使用PrintWriter的println方法寫入student.txt,每行一個學生,學生的每一個屬性之間用|做爲分隔。使用Scanner或者BufferedReader將student.txt的數據讀出。(截圖關鍵代碼,出現學號)

三個Student對象:

writeStudent方法:

使用BufferedReader方法讀取student.txt

控制檯輸出以及記事本內容:

1.2 生成文件大小多少(使用右鍵文件屬性查看)?分析該文件大小



文件大小爲48個字節,其中每一個英文字符以及」|」佔一個字節,每一箇中文字符佔兩個字節,換行符佔兩個字節,所以每一行爲16個字節,三行總共48個字節。

1.3 若是調用PrintWriter的println方法,但在後面不close。文件大小是多少?爲何?

大小爲0字節。
由於printWrite會將數據寫到緩衝區內,在最後使用close進行關閉時,它會將緩衝區的內容送出來,因此當沒有使用close進行關閉的時候,數據就會在緩衝區內丟失,所以若是在關閉前使用了flush方法將緩衝區的內容先送出來,仍是能夠將數據寫入文件的。

2. 緩衝流

2.1 使用PrintWriter往文件裏寫入1千萬行(隨便什麼內容都行),而後對比使用BufferedReader與使用Scanner從該文件中讀取數據的速度(只讀取,不輸出),使用哪一種方法快?截取測試源代碼,出現學號。請詳細分析緣由?提示:可使用junit4對比運行時間





能夠看出使用BufferedReader讀取文件更快,這是由於Scanner會對輸入數據進行類解析,而BufferedReader只是簡單地讀取字符序列。而且BufferedReader相對於Scanner有更大的緩衝區,能夠進行更少的輸入輸出操做,所以會更快一些。

2.2 將PrintWriter換成BufferedWriter,觀察寫入文件的速度是否有提高。記錄二者的運行時間。試分析緣由。




由上圖能夠看出,速度會有提高,這是由於BufferedWriter具備更大緩衝區的關係。

3. 字符編碼

3.1 現有EncodeTest.txt 文件,包含一些中文,該文件使用UTF-8編碼。使用FileReader與BufferedReader將EncodeTest.txt的文本讀入並輸出。是否有亂碼?爲何會有亂碼?如何解決?(截圖關鍵代碼,出現學號)


運行結果:

能夠看出會產生亂碼,這是由於FileReader繼承自InputStreamReader,並利用它完成字節流到字符流的轉換,並且在轉換時採起的字符集爲系統的默認字符集,即GBK。因而在UTF-8 -> GBK -> UTF-8的過程當中編碼出現損失,致使其出現了亂碼。解決方法以下:

3.2 編寫方法convertGBK2UTF8(String src, String dst),能夠將以GBK編碼的源文件src轉換成以UTF8編碼的目的文件dst。

方法以下:

4. 字節流、二進制文件:DataInputStream, DataOutputStream、ObjectInputStream

4.1 參考DataStream目錄相關代碼,嘗試將三個學生對象的數據寫入文件,而後從文件讀出並顯示。(截圖關鍵代碼,出現學號)





4.2 這裏生成的文件和題目1生成的文件有何不同?生成的文件有多大?分析該文件大小?將該文件大小和題目1生成的文件對比是大了仍是小了,爲何?存儲數據的時候,究竟是二進制文件比較節省空間仍是文本文件比較節省空間?使用二進制存儲文件有何好處?

這裏生成的文件是以.data爲後綴名的數據文件,在這具體是指一個二進制文件。

能夠看到生成的文件爲72個字節,其中一個int爲4個字節,一個漢字爲3個字節,代表字符串所佔的字節數爲2個字節,一個double爲8個字節,所以一行的字節數爲4+3+3+4+8+2=24,三行的字節數爲24*3=72.
和題目一的文件相比變大了,有上面的分析能夠看出,存儲一個int,double和中文字符所需的字節數都變多了,所以文件比第一題的大。
雖然從上面的分析來看彷佛是文本文件更能節省空間,可是這個仍是要看具體狀況,當存儲的數值很小的時候,文本文件所佔用的空間可能會更小,可是若是要存儲大量的數據,仍是二進制文件更能節省空間。
使用二進制存儲文件的好處以下:

  • 二進制文件更能節省存儲空間
  • 對於某些比較精確的數據,二進制不會形成有效位數的丟失
  • 計算機中使用的語言是二進制語言,所以用二進制存儲就能夠省去語言的轉換過程

4.3 使用wxMEdit的16進制模式(或者其餘文本編輯器的16進制模式)打開student.data,分析數據在文件中是如何存儲的。


有點懶,就分析一行,其他兩行相似:
00 00 00 01表明1
00 06 表明字符所佔用的字節數,一箇中文字符佔三個字節
E5 BC A0 E4 B8 89表明張三
00 00 00 13 表明’19’
40 50 40 00 00 00 00 00 表明19.65

4.4 使用ObjectInputStream(讀), ObjectOutputStream(寫)讀寫學生。(截圖關鍵代碼,出現學號) //參考ObjectStreamTest目錄



5. Scanner基本概念組裝對象

編寫public static List<Student> readStudents(String fileName)從fileName指定的文本文件中讀取全部學生,並將其放入到一個List中。應該使用那些IO相關的類?說說你的選擇理由。


答:要使用到的類有File類,FileInputStream類,InputStreamReader類,BufferedReader類,其中BufferedReader類中帶有的較大的緩衝區可讓咱們更快的進行數據的讀寫。

6. 選作:RandomAccessFile

6.1 使用RandomAccessFile實現題目1.1。(截圖關鍵代碼,出現學號)




6.2 分析文件大小


大小爲72個字節,和4.2中的分析同樣。

6.3 編寫一個函數public Student getStuByIndext(int index),能夠根據序號index使用RandomAccessFile從文件中將該學生的信息取出。(截圖關鍵代碼,出現學號)。並回答,哪裏體現了RandomAccessFile對文件的隨機訪問特性。




RandomAccessFile能夠經過seek(),skipBytes()以及length等方法定位到文件的任何一個位置,在此基位置上進行一些文件的操做。

7. 文件操做

編寫一個程序,能夠根據指定目錄和文件名,搜索該目錄及子目錄下的全部文件,若是沒有找到指定文件名,則顯示無匹配,不然將全部找到的文件名與文件夾名顯示出來。

7.1 編寫public static void findFile(String path,String filename)函數,以path指定的路徑爲根目錄,使用遞歸方式,在其目錄與子目錄下查找全部和filename相同的文件名,一旦找到就立刻輸出到控制檯。(截圖關鍵代碼,出現學號)



7.2 使用隊列、使用圖形界面、使用Java NIO.2完成(任選1)




NIO.2的File工具類提供了一個walkFileTree來進行遍歷,相比於上一題的遞歸,更加高效且優雅,而後在內部使用了遍歷行爲控制器FileVisitor,它是一個接口,裏面提供四個方法來指定遍歷過程當中的事件處理,可是實際上,我在遍歷時用的是直接繼承FileVisitor的適配器SimpleFileVisitor,它相較於FileVisitor的好處就是能夠不用實現四個方法,只需實現須要的方法便可。可是發現使用NIO.2遍歷的文件彷佛不會區分大小寫耶。

7.3 選作:性能測試,測試你的findFile查找匹配文件的速度。有什麼解決方案,可讓查找速度更快一些。好比相似Everything的搜索速度。

測試findFile的運行速度:

使用普通遍歷法的運行時間:

使用NIO.2方法的遍歷時間:

經過上面圖片能夠看出,使用NIO.2的運行時間更短,其實上題就說過了,使用NIO.2能夠提升遍歷的效率。

7.4 選作:實現刪掉指定目錄(若是該目錄非空,刪除掉該目錄下及其子目錄下的全部文件與目錄)。

7.5 選作:將指定目錄及子目錄下的全部.java文件,轉化成UTF-8編碼格式,並測試。




8. 正則表達式

8.1 使用正則表達式判斷給定的字符串是不是10進制數字格式?嘗試編程進行驗證,要給測試數據集及運行結果(能夠轉化爲PTA)。(截圖關鍵代碼,出現學號)


8.2 解釋本身編寫的正則表達式。

我編寫的正則表達式爲^[-\\+]?[\\d]+[\\.]?[\\d]+$
^表明匹配輸入字符串的開始位置
[-\\+]?表明字符串中」-」和」+」能夠出現0次或1次
[\\d]+表明數字能夠出現1次或屢次
[\\.]?表明」.」能夠出現0次或1次
$表明匹配輸入字符串的結束位置

相關文章
相關標籤/搜索