一、File 類
- file.list() 列出文件夾的所有文件
- FilenameFilter 接口 file.list(FilenameFilter filter) 時選擇性過濾文件
- 用 File 進行目錄遍歷
- 策略模式:對特定的文件進行特定的處理
- File 讀取文件信息(絕對路徑、可讀、可寫、最后修改時間等)
- File 刪除文件、重命名、創建文件夾
二、Tips
匿名內部類的使用場景
- 特定的,一次性使用的類。優點:能夠將解決特定問題的代碼聚攏到一起。缺點:代碼不易讀。
- 傳向匿名內部類的參數必須為 final(這樣設計和局部變量作用域有關)
大端法和小端法
- 大端法:對于int、float等大于一個字節的數據,順序儲存字節
- 小端法:逆序儲存字節
- ByteBuffer 可設置大端法或小端法儲存數據
三、InputStream/OutputStream
InputStream API 方法
InputStream API
InputStream 類圖
InputStream 類圖
OutputStream API 方法
OutputStream API
OutputStream 類圖
OutputStream 類圖
- 裝飾模式:減少了類的數量,但是創建一個流時往往要新建多個對象。
四、Reader/Writer
- BufferedReader 為什么沒有繼承 FilterReader
- Reader 和 InputStream 如何適配(適配器模式)
- 類繼承圖
五、InputStream/OutputStream 和 Reader/Writer 的比較
- InputStream/OutputStream 處理字節(byte),某些類添加了將字節轉換成字符的功能,但會出現很多亂碼問題;
- Reader/Writer 處理字符(char)
六、RandomAccessFile
- 獨立于 InputStream/OutputStream 系統存在的類,繼承了 DataInput 和 DataOutput 接口??蓪ξ募M行讀寫操作,可看做包含了 DataInputStream/DataOutputStream 兩者的功能。
- 行為與 InputStream/OutputStream 本質上有不同:游標可以移動到文件的任意位置。InputStream/OutputStream 有 mark() 和 reset() 方法,但是局限性很大。RandomAccessFile 的 seek() 方法很靈活。
- getFilePointer(): find where you are in the file
- seek(): move to a new point in the file
- length(): determined the maximun size of the file
- 兩種模式 "r","rw",沒有 "w" 模式
七、標準 I/O
- System.out 和 System.err 是裝飾好的,System.in 要進行手工裝飾
- System.out 是一個 PrintWriter 對象
- 可以將標準 I/O 重定向輸出,setIn(InputStream),setOut(PrintStream),setErr(PrintStream),在日志在屏幕上打印難以看清時將其重定向到文件會很有用
八、Buffer and Channel
- 可以獲取 Channel 的類:FileInputStream、FileOutputStream、RandomAccessFile
- 為 Buffer 分配資源:allocate\allocateDirect,手動分配以提高效率,要根據具體運行環境調參
- buffer.flip() 為寫做準備;buffer.clear() 為讀做準備
- channel:transferTo、transferFrom 不同流間傳輸
- 獲取 ByteBuffer 不同類型數據的 View:asShortBuffer() 等
NIO 類關系圖:
new io
九、Memory-mapped files
- 如果文件太大,不能一次性讀入內存,可以使用 Memory-mapped file 方便操作。對于大文件,此類可以大大提高速度
十、File locking
- 對文件全部或部分加鎖,鎖對于非java應用也是可見的(取決于操作系統,用FileLock.isShared()判斷)
- tryLock(long position,long size,boolean shared) 獲取不到鎖則返回 null
- lock(long position,long size,boolean shared) 獲取不到鎖則等待,一直到獲取成功,或線程終止
十一、Compression
- 畫類圖
- DeflaterOutputStream 和 InflaterInputStream 處理壓縮文件的類繼承自 InputStream 和 OutputStream
- GZIPOutputStream 和 GZIPInputStream 用法和傳統 InputStream 和 OutputStream 類似
- ZipOutputStream 和 ZipInputStream 可以進行多個文件的壓縮(putNextEntry())
十二、Object serialization 序列化
- 繼承 Serialization(標簽接口,不包含方法)的類可以進行序列化,序列化即將對象轉換成bytes儲存起來,隨后可以恢復成原樣。
- RMI 和 JavaBean 都需要序列化的支持。
- 序列化不僅儲存這個類本身,還會儲存它引用的類
- 在反序列化類時,如果這個類沒有被加載,則會報 ClassNotFound 錯誤
自定義序列化
有些信息,比如用戶密碼,你不想將其序列化存到文件中,這時需要自定義序列化
- 繼承 Externalizable 接口,并重寫 readExternal() 和 writeExternal()。此種方法反序列化時要調用構造方法,因此沒有保存其引用的對象,引用對象需要在 readExternal() 和 writeExternal() 顯示保存。見 P708 的代碼。
- 繼承 Serialization 接口,反序列化時并不經過構造方法。private 成員變量也會被序列化,如果想避開某個成員變量(如密碼),可以使用 transient 關鍵詞
- 繼承 Serialization 接口,并添加 readObject 方法和 WriteObject 方法,并在需要時調用 defaultReadObject 方法和 defaultWriteObject
注意事項
- 兩個對象 A、B 同時引用第三個對象 C(P714),只要是在同一個流中序列化和反序列化,同樣的對象將會恢復成同一個引用,即完全恢復對象網。
- static 成員不會被自動序列化