Java的IO 介紹 [同步/非同步/阻塞/非阻塞 I/O 原理介紹]
Java的IO 介紹 [同步/非同步/阻塞/非阻塞 I/O 原理介紹]
資料來源: https://mp.weixin.qq.com/s/ptI0K79uBfQj9TF0bTINng
種類介紹:
BIO(阻塞I / O):同步阻塞I / O模式。
同步阻塞模式:這種模式下,我們的工作模式是先來到廚房,開始燒水,並坐在水壺面前一直等著水燒開。
NIO(新I / O):同步非阻塞模式。
同步非阻塞模式:這種模式下,我們的工作模式是先來到廚房,開始燒水,但是我們不一直坐在水壺前面等,而是回到客廳看電視,然後每隔幾分鐘到廚房看一下水有沒有燒開。
AIO(異步I / O):異步非阻塞I / O模型。
異步非阻塞I / O模型:這種模式下,我們的工作模式是先來到廚房,開始燒水,我們不一一直坐在水壺前面等,也不隔一段時間去看一下,而是在客廳看電視,水壺上面有個開關,水燒開之後他會通知我。
阻塞VS非阻塞:人是否坐在水壺前面一直等。
同步VS異步:水壺是不是在水燒開之後主動通知人。
應用場合:
BIO方式適用於連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,並發局限於應用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解。
NIO方式適用於連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,並發局限於應用中,編程比較複雜,JDK1.4開始支持。
AIO方式適用於連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用OS參與並發操作,編程比較複雜,JDK7開始支持。
JAVA程式碼
BIO code:
//初始化對象 User1 user = new User1(); user.setName(“hollis”); user.setAge(23); 系統。out .println(user); //將Obj寫入文件 ObjectOutputStream oos = null ; try { oos = new ObjectOutputStream(new FileOutputStream(“tempFile”)); oos.writeObject(用戶); } catch (IOException e){ e.printStackTrace(); } finally { IOUtils.closeQuietly(oos); } //從文件中讀取Obj 文件文件= 新 文件(“tempFile”); ObjectInputStream ois = null ; try { ois = new ObjectInputStream(new FileInputStream(file)); User1 newUser =(User1)ois.readObject(); 系統。out .println(newUser); } catch (IOException e){ e.printStackTrace(); } catch (ClassNotFoundException e){ e.printStackTrace(); } finally { IOUtils.closeQuietly(ois); 嘗試 { FileUtils.forceDelete(file); } catch (IOException e){ e.printStackTrace(); } } //初始化Object User1 user = new User1(); user.setName(“hollis”); user.setAge(23); 系統。out .println(user); //將Obj寫入文件 ObjectOutputStream oos = null ; try { oos = new ObjectOutputStream(new FileOutputStream(“tempFile”)); oos.writeObject(用戶); } catch (IOException e){ e.printStackTrace(); } 終於 { IOUtils.closeQuietly(oos); } //從文件 文件中讀取Obj文件= 新 文件(“tempFile”); ObjectInputStream ois = null ; try { ois = new ObjectInputStream(new FileInputStream(file)); User1 newUser =(User1)ois.readObject(); 系統。out .println(newUser); } catch (IOException e){ e.printStackTrace(); } catch (ClassNotFoundException e){ e.printStackTrace(); } finally { IOUtils.closeQuietly(OIS); 嘗試 { FileUtils.forceDelete(file); } catch (IOException e){ e.printStackTrace(); } }
NIO code:
static void readNIO() { String pathname = “C:\\ Users \\ adew \\ Desktop \\ jd-gui.cfg” ; FileInputStream fin = null ; try { fin = new FileInputStream( new File(pathname)); FileChannel channel = fin.getChannel(); int capacity = 100 ; //字節 ByteBuffer bf = ByteBuffer.allocate(capacity); int length = -1 ; while ((length = channel.read(bf))!= -1){ bf.clear(); byte [] bytes = bf.array(); 系統。out .write(bytes, 0,length); 系統。out .println(); } channel.close(); } catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } finally { if (fin!= null){ try { fin.close(); } catch (IOException e){ e.printStackTrace(); } } } } 靜態 無效 writeNIO() { 字符串文件名= “out.txt” ; FileOutputStream fos = null ; 試試 { fos = new FileOutputStream(new File(filename)); FileChannel channel = fos.getChannel(); ByteBuffer src = Charset.forName(“utf8”)。encode(“你好你好你好你好你好”); int length = 0 ; 而 ((length = channel.write(src))!= 0){ System。out .println(“寫入長度:” + length); } } 捕獲 (FileNotFoundException異常E){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } finally { if (fos!= null){ try { fos.close(); } catch (IOException e){ e.printStackTrace(); } } } }
AIO code:
public class ReadFromFile { public static void main(String [] args)throws Exception { Path file = Paths。get(“/usr/a.txt”); AsynchronousFileChannel channel = AsynchronousFileChannel.open(file); ByteBuffer buffer = ByteBuffer.allocate(100 _000); Future <Integer> result = channel.read(buffer, 0); while (!result.isDone()){ ProfitCalculator.calculateTax(); } Integer bytesRead = result。get(); 系統。出.println(“Bytes read [” + bytesRead + “]”); } } 類 ProfitCalculator { 公共 ProfitCalculator() { } 公共 靜態 無效 calculateTax的() { } } 公共 類 將writeToFile { 公共 靜態 無效 主要(字串[] args)拋出異常 { AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open( 路徑。獲得(“/ asynchronous.txt“),StandardOpenOption.READ, StandardOpenOption.WRITE,StandardOpenOption.CREATE); CompletionHandler <Integer,Object> handler = new CompletionHandler <Integer,Object>(){ @ Override public void completed(整數結果,對象附件) { System。out .println(“Attachment:” + attachment + “” + result + “bytes written”); 系統。out .println(“CompletionHandler Thread ID:” + Thread.currentThread()。getId()); @ 覆蓋 public void failed(Throwable e,Object attachment) { System.err.println(“Attachment:” + attachment + “failed with:”); e.printStackTrace(); } }; 系統。out .println(“主線程ID:” + Thread.currentThread()。getId()); fileChannel.write(ByteBuffer.wrap(“Sample” .getBytes()), 0, “First Write”, handler); fileChannel.write(ByteBuffer.wrap(“Box” .getBytes()), , “第二次寫”, 處理程序); } }