Java的I/O操作包在java.io下,里面有很多類,大概可以分為以下4類:
1.字節操作的I/O接口:InputStream 和OutputStream 2.字符操作的I/O接口:Writer ,Reader 3.磁盤操作的I/O接口:File 4.網絡操作的I/O接口:Socket (Socket不在java.io包下,但也跟I/O有很大關系) 總結起來就是傳輸數據的數據格式和傳輸數據的方式這兩種,所以說I/O的核心問題要么是數據格式影響I/O操作,要么是傳輸方式影響I/O操作(《深入分析Java Web技術內幕》)。
1.基本I/O 網絡傳輸和磁盤存儲的最小單元是字節,但是在程序中通常的操作數據形式是字符,所以就有了字節與字符的轉化。在這個轉化過程中,有一點需要注意的是編碼的轉換,這是個經常會遇到的問題,所以解決亂碼問題是Java中的一個大頭。
轉換接口有 InputStreamReader/OutputStreamWriter,中間用到了適配器模式。InputStreamReader實現了Read接口,并且持有了InputStream的引用(通過StreamDecoder,此類用來編碼)。
2.磁盤I/O 幾種訪問文件的方式 1)標準訪問文件方式
應用程序調用系統的read()和wirte()系統調用,與系統內核的高速緩存打交道,然后高速緩存與磁盤打交道。2)直接I/O的方式
應用程序直接訪問磁盤數據,而不經過系統內核數據緩沖區(比如各種數據庫應用程序)3)同步訪問文件方式
數據的讀寫都是同步操作與1)不同的是,只有當數據成功寫到磁盤才返回成功給應用程序4)異步訪問文件
訪問數據的線程發出請求后繼續處理其他的事情不必傻傻等待5)內存映射
操作系統將內存中的某一塊區域與磁盤中的文件關聯起來,當訪問內存中的一段數據時,轉換為訪問文件的數據,數據是共享的Java訪問磁盤文件 File 類 File并不代表一個真實存在的文件對象,可能是一個文件或者是一個包含多個文件的目錄。為什么這么設計呢,因為大多數情況下,我們主要關心的是這個文件的操作,并不關心這個文件是否真的存在。比如手機通訊錄的電話號碼有上百個,我們關心的是有沒有這個朋友的號碼,但是不會去經常檢測這個號碼是否到底能不能打通,在真正打的時候才會去檢測能不能用。就像檢測一個文件是否存在就在真正要讀取這個文件的時候。 FileInputStream創建時會創建一個FileDescriptor對象,該對象就是真正代表一個存在的文件對象的描述。
Java序列化 持久化對象,需要實現java.io.Serializable接口 1.當父類繼承Serializable接口時,所有子類都可以被序列化 2.子類實現Serializable接口,父類沒有,父類中的屬性不能被序列化,數據丟失,子類中的屬性可以正確序列化 3.屬性是對象,該對象也要實現Serializable
網絡I/O 1. TCP的狀態轉化( 三次握手與四次揮手) 2.Java Socket工作機制
NIO 核心:Buffer,Channel,Selector 理解BIO,NIO的思想 阻塞IO,讀寫阻塞線程失去CUP使用權,線程數量,線程優先級,資源競爭,同步等等問題 基于NIO的Socket請求處理:Selector監聽一組Channel上的I/O狀態,將數據分配到對應的數據Buffer中。一個線程來監聽,監聽客戶端連接的請求,另外一個線程來處理所有連接的數據交互,每個連接的數據交互都不是阻塞方式。
NIO的數據訪問方式比傳統方式的優勢 NIO兩個優化方法:FileChannel.transferTo/From FileChannel.map 減少了數據從系統內核到用戶空間的復制。
新聞熱點
疑難解答