在Java中的java.io
包中定義了許多類專門負責處理各類方式的輸入與輸出。其中,全部輸入流類都是抽象類InputStream
(字節輸入流)或抽象類Reader
(字符輸入流)的子類,而全部輸出流類都是抽象類OutputStream
(字節輸出流)或抽象類Writer
(字符輸出流)的子類。
java
InputStream
類的層次結構
Reader
類的層次結構
正則表達式
OutputStream
類的層次結構
Writer
類的層次結構
編程
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 | 獲取文件最後修改時間 |
使用流與文件改造你的圖書館管理系統或購物車。編輯器
答:我在剛開始的時候先經過靜態初始化塊初始圖書館的數據而後將初始化後的圖書數據使用對象流ObjectOutputStream
寫入文件Book.data
進行保存,用戶模塊相似,而後在兩個模塊中各寫一個保存修改後文件數據的方法用於存儲操做過程當中數據變化後的文件。用對象流寫入文件是以十六進制保存的,由於對象流原本就是適合於網絡之間的傳輸。函數
用到了InputStream
、OutputStream
接口下的ObjectInputStream
和ObjectOutputStream
子類,還有文件類File
,在對對象進行序列化的時候還用到了Serializable
接口,使用對象流是爲了能夠將一個對象的完整信息都存入文件,若是隻是普通的字節字符流則沒辦法作到這點,而後使用對象流寫入或讀取對象時,要保證對象時序列化的,這是爲了保證能把對象寫入文件,而且從文件中正確讀到程序中,這時候就要用到Serializable
接口來實現對象的序列化。工具
初始化Library
:
保存修改後的Library
文件:
初始化用戶模塊:
保存修改事後的用戶信息保存到文件中:
性能
一開始能夠只用控制檯,不必定要用Web。學習
須要將每週的代碼統計狀況融合到一張表中。
彷佛達到了第一週設置的目標(◦˙▽˙◦)
周次 | 總代碼量 | 新增代碼量 | 總文件數 | 新增文件數 |
---|---|---|---|---|
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 |
將Student對象(屬性:int id, String name,int age,double grade)寫入文件student.data、從文件讀出顯示。
三個Student對象:
writeStudent方法:
使用BufferedReader方法讀取student.txt
控制檯輸出以及記事本內容:
文件大小爲48個字節,其中每一個英文字符以及」|」佔一個字節,每一箇中文字符佔兩個字節,換行符佔兩個字節,所以每一行爲16個字節,三行總共48個字節。
大小爲0字節。
由於printWrite會將數據寫到緩衝區內,在最後使用close進行關閉時,它會將緩衝區的內容送出來,因此當沒有使用close進行關閉的時候,數據就會在緩衝區內丟失,所以若是在關閉前使用了flush方法將緩衝區的內容先送出來,仍是能夠將數據寫入文件的。
能夠看出使用BufferedReader
讀取文件更快,這是由於Scanner
會對輸入數據進行類解析,而BufferedReader
只是簡單地讀取字符序列。而且BufferedReader
相對於Scanner
有更大的緩衝區,能夠進行更少的輸入輸出操做,所以會更快一些。
由上圖能夠看出,速度會有提高,這是由於BufferedWriter具備更大緩衝區的關係。
運行結果:
能夠看出會產生亂碼,這是由於FileReader
繼承自InputStreamReader
,並利用它完成字節流到字符流的轉換,並且在轉換時採起的字符集爲系統的默認字符集,即GBK。因而在UTF-8 -> GBK -> UTF-8的過程當中編碼出現損失,致使其出現了亂碼。解決方法以下:
convertGBK2UTF8(String src, String dst)
,能夠將以GBK編碼的源文件src轉換成以UTF8編碼的目的文件dst。方法以下:
這裏生成的文件是以.data爲後綴名的數據文件,在這具體是指一個二進制文件。
能夠看到生成的文件爲72個字節,其中一個int爲4個字節,一個漢字爲3個字節,代表字符串所佔的字節數爲2個字節,一個double爲8個字節,所以一行的字節數爲4+3+3+4+8+2=24,三行的字節數爲24*3=72.
和題目一的文件相比變大了,有上面的分析能夠看出,存儲一個int,double和中文字符所需的字節數都變多了,所以文件比第一題的大。
雖然從上面的分析來看彷佛是文本文件更能節省空間,可是這個仍是要看具體狀況,當存儲的數值很小的時候,文本文件所佔用的空間可能會更小,可是若是要存儲大量的數據,仍是二進制文件更能節省空間。
使用二進制存儲文件的好處以下:
有點懶,就分析一行,其他兩行相似:
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
編寫public static List<Student> readStudents(String fileName)
從fileName指定的文本文件中讀取全部學生,並將其放入到一個List中。應該使用那些IO相關的類?說說你的選擇理由。
答:要使用到的類有File類,FileInputStream類,InputStreamReader類,BufferedReader類,其中BufferedReader類中帶有的較大的緩衝區可讓咱們更快的進行數據的讀寫。
大小爲72個字節,和4.2中的分析同樣。
public Student getStuByIndext(int index)
,能夠根據序號index使用RandomAccessFile從文件中將該學生的信息取出。(截圖關鍵代碼,出現學號)。並回答,哪裏體現了RandomAccessFile對文件的隨機訪問特性。
RandomAccessFile
能夠經過seek()
,skipBytes()
以及length
等方法定位到文件的任何一個位置,在此基位置上進行一些文件的操做。
編寫一個程序,能夠根據指定目錄和文件名,搜索該目錄及子目錄下的全部文件,若是沒有找到指定文件名,則顯示無匹配,不然將全部找到的文件名與文件夾名顯示出來。
public static void findFile(String path,String filename)
函數,以path指定的路徑爲根目錄,使用遞歸方式,在其目錄與子目錄下查找全部和filename相同的文件名,一旦找到就立刻輸出到控制檯。(截圖關鍵代碼,出現學號)
NIO.2的File工具類提供了一個walkFileTree
來進行遍歷,相比於上一題的遞歸,更加高效且優雅,而後在內部使用了遍歷行爲控制器FileVisitor
,它是一個接口,裏面提供四個方法來指定遍歷過程當中的事件處理,可是實際上,我在遍歷時用的是直接繼承FileVisitor
的適配器SimpleFileVisitor
,它相較於FileVisitor
的好處就是能夠不用實現四個方法,只需實現須要的方法便可。可是發現使用NIO.2遍歷的文件彷佛不會區分大小寫耶。
Everything
的搜索速度。測試findFile
的運行速度:
使用普通遍歷法的運行時間:
使用NIO.2方法的遍歷時間:
經過上面圖片能夠看出,使用NIO.2的運行時間更短,其實上題就說過了,使用NIO.2能夠提升遍歷的效率。
我編寫的正則表達式爲^[-\\+]?[\\d]+[\\.]?[\\d]+$
^
表明匹配輸入字符串的開始位置
[-\\+]?
表明字符串中」-」和」+」能夠出現0次或1次
[\\d]+
表明數字能夠出現1次或屢次
[\\.]?
表明」.」能夠出現0次或1次
$
表明匹配輸入字符串的結束位置