裝飾者模式、適配器模式java
BIO是一個鏈接一個線程。面試
傳統的同步阻塞模型開發中,ServerSocket負責綁定IP地址,啓動監聽端口;Socket負責發起鏈接操做。鏈接成功後,雙方經過輸入和輸出流進行同步阻塞式通訊。編程
該模型最大的問題就是缺少彈性伸縮能力,當客戶端併發訪問量增長後,服務端的線程個數和客戶端併發訪問數呈1:1的正比關係,Java中的線程也是比較寶貴的系統資源,線程數量快速膨脹後,系統的性能將急劇降低,隨着訪問量的繼續增大,系統最終就死-掉-了。設計模式
NIO提供了與傳統BIO模型中的Socket和ServerSocket相對應的SocketChannel和ServerSocketChannel兩種不一樣的套接字通道實現。兩種通道都支持阻塞和非阻塞兩種模式。數組
對於低負載、低併發的應用程序,可使用同步阻塞I/O來提高開發速率和更好的維護性;對於高負載、高併發的(網絡)應用,應使用NIO的非阻塞模式來開發。安全
緩衝區服務器
java.nio.Buffer
是一個抽象類。網絡
在NIO庫中,全部數據都是用緩衝區處理的,緩衝區包含一些要寫入或者讀出的數據。數據結構
緩衝區其實是一個數組,並提供了對數據結構化訪問以及維護讀寫位置等信息。如:ByteBuffer、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。併發
通道
咱們對數據的讀取和寫入要經過Channel,它就像水管同樣,是一個通道。通道不一樣於流的地方就是通道是雙向的,能夠用於讀、寫和同時讀寫操做。
底層的操做系統的通道通常都是全雙工的,因此全雙工的Channel比流能更好的映射底層操做系統的API。
多路複用器
Selector提供選擇已經就緒的任務的能力:Selector會不斷輪詢註冊在其上的Channel,若是某個Channel上面發生讀或者寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,而後經過SelectionKey能夠獲取就緒Channel的集合,進行後續的I/O操做。
一個Selector能夠同時輪詢多個Channel,由於JDK使用了epoll()代替傳統的select實現,因此沒有最大鏈接句柄1024/2048的限制。因此,只須要一個線程負責Selector的輪詢,就能夠接入成千上萬的客戶端。
NIO是一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。
適用場景:聊天服務器
NIO 2.0引入了新的異步通道的概念,並提供了異步文件通道和異步套接字通道的實現。
異步的套接字通道是真正的異步非阻塞I/O,對應於UNIX網絡編程中的事件驅動I/O(AIO)。他不須要過多的Selector對註冊的通道進行輪詢便可實現異步讀寫,從而簡化了NIO的編程模型。
AIO是一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理。
適用場景:相冊服務器
主體部分
按字節讀,可用於文件、圖片、視頻、音頻
OutputStream、InputStream
按字符讀,通常用於文件
Writer、Reader
Java中字符是採用Unicode標準,一個字符是16位,即一個字符使用兩個字節來表示。爲此,JAVA中引入了處理字符的流。由於數據編碼的不一樣,而有了對字符進行高效操做的流對象。本質其實就是基於字節流讀取時,去查了指定的碼錶。
字節流沒有緩衝區,是直接輸出的,而字符流是輸出到緩衝區的。所以在輸出時,字節流不調用close()方法時,信息已經輸出了,而字符流只有在調用close()方法關閉緩衝區時,信息才輸出。要想字符流在未關閉時輸出信息,則須要手動調用flush()方法。
輔助流式部分的類,如:File、RandomAccessFile、FileDescriptor
文件讀取部分的與安全相關的類,如:SerializablePermission;
與本地操做系統相關的文件系統的類,如:FileSystem、Win32FileSystem、WinNTFileSystem。
什麼是IO流?
它是一種數據的流從源頭流到目的地。好比文件拷貝,輸入流和輸出流都包括了。輸入流從文件中讀取數據存儲到進程(process)中,輸出流從進程中讀取數據而後寫入到目標文件。
字節流和字符流的區別。
字節流在JDK1.0中就被引進了,用於操做包含ASCII字符的文件。JAVA也支持其餘的字符如Unicode,爲了讀取包含Unicode字符的文件,JAVA語言設計者在JDK1.1中引入了字符流。ASCII做爲Unicode的子集,對於英語字符的文件,能夠可使用字節流也可使用字符流。
Java中流類的超類主要由那些?
FileInputStream和FileOutputStream是什麼?
這是在拷貝文件操做的時候,常常用到的兩個類。在處理小文件的時候,它們性能表現還不錯,在大文件的時候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)
public class InputAndOutputBuffering { public static void main(String args[]) throws IOException { FileInputStream fistream = new FileInputStream("pqr.txt"); BufferedInputStream bistream = new BufferedInputStream(fistream); FileOutputStream fostream = new FileOutputStream("xyz.txt"); BufferedOutputStream bostream = new BufferedOutputStream(fostream); int temp; while( ( temp = bistream.read() ) != -1 ) { bostream.write(temp); System.out.print((char) temp); } bostream.close(); fostream.close(); bistream.close(); fistream.close(); } }
字節流和字符流,你更喜歡使用拿一個?
我的來講,更喜歡使用字符流,由於他們更新一些。許多在字符流中存在的特性,字節流中不存在。好比使用BufferedReader而不是BufferedInputStreams或DataInputStream,使用newLine()方法來讀取下一行,可是在字節流中咱們須要作額外的操做。
System.out.println()
是什麼?
println
是PrintStream的一個方法。out
是一個靜態PrintStream類型的成員變量,System
是一個java.lang包中的類,用於和底層的操做系統進行交互。
什麼是Filter流?
Filter Stream是一種IO流主要做用是用來對存在的流增長一些額外的功能,像給目標文件增長源文件中不存在的行數,或者增長拷貝的性能。
有哪些可用的Filter流?
在java.io包中主要由4個可用的filter Stream。兩個字節filter stream,兩個字符filter stream,分別是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter。這些類是抽象類,不能被實例化的。
SequenceInputStream的做用?
在拷貝多個文件到一個目標文件的時候是很是有用的。可用使用不多的代碼實現
public class TwoFiles { public static void main(String args[]) throws IOException { FileInputStream fistream1 = new FileInputStream("A.txt"); // first source file FileInputStream fistream2 = new FileInputStream("B.txt"); //second source file SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2); FileOutputStream fostream = new FileOutputStream("C.txt");// destination file int temp; while( ( temp = sistream.read() ) != -1) { System.out.print( (char) temp ); // to print at DOS prompt fostream.write(temp); // to write to file } fostream.close(); sistream.close(); fistream1.close(); fistream2.close(); } }
說說PrintStream和PrintWriter
他們兩個的功能相同,可是屬於不一樣的分類。字節流和字符流。他們都有println()方法。
在文件拷貝的時候,那一種流可用提高更多的性能?
在字節流的時候,使用BufferedInputStream和BufferedOutputStream。
在字符流的時候,使用BufferedReader 和 BufferedWriter
說說管道流(Piped Stream)
有四種管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.在多個線程或進程中傳遞數據的時候管道流很是有用。
說說File類
它不屬於 IO流,也不是用於文件操做的,它主要用於知道一個文件的屬性,讀寫權限,大小等信息。
說說RandomAccessFile?
它在java.io包中是一個特殊的類,既不是輸入流也不是輸出流,它二者均可以作到。他是Object的直接子類。一般來講,一個流只有一個功能,要麼讀,要麼寫。可是RandomAccessFile既能夠讀文件,也能夠寫文件。 DataInputStream 和 DataOutStream有的方法,在RandomAccessFile中都存在。
做者:艾賀521 連接:https://www.imooc.com/article/24305