# Java IO ä½ç³»
[toc]
Java IO æ¯ä¸ä¸ªåºå¤§çç¥è¯ä½ç³»ï¼å¾å¤äººå¦çå¦çå°±ä¼å¦æµäºï¼å
æ¬æå¨å
乿¯å¦æ¤ï¼æä»¥æ¬æå°ä¼ä» Java ç BIO å¼å§ï¼ä¸æ¥ä¸æ¥æ·±å
¥å¦ä¹ ï¼å¼åº JDK1.4 ä¹ååºç°ç NIO ææ¯ï¼å¯¹æ¯ NIO ä¸ BIO çåºå«ï¼ç¶å对 NIO ä¸éè¦çä¸ä¸ªç»æé¨åè¿è¡è®²è§£ï¼ç¼å²åºãééãéæ©å¨ï¼ï¼æåå®ç°ä¸ä¸ª**ç®æç客æ·ç«¯ä¸æå¡å¨éä¿¡åè½**ã

## ä¼ ç»ç BIO
Java IOæµæ¯ä¸ä¸ªåºå¤§ççæç¯å¢ï¼å
¶å
鍿ä¾äºå¾å¤ä¸åç**è¾å
¥æµåè¾åºæµ**ï¼ç»åä¸å»è¿æåèæµåå符æµï¼çè³è¿æ**ç¼å²æµ**æé« IO æ§è½ï¼è½¬æ¢æµå°åèæµè½¬æ¢ä¸ºå符æµÂ·Â·Â·Â·Â·Â·çå°è¿äºå°±å·²ç»å¯¹ IO äº§çææ§äºï¼å¨æ¥å¸¸å¼åä¸å°ä¸äºå¯¹æä»¶ç IO æä½ï¼è½ç¶ apache å·²ç»æä¾äº `Commons IO` è¿ç§å°è£
好çç»ä»¶ï¼ä½é¢å¯¹ç¹æ®åºæ¯æ¶ï¼æä»¬ä»éè¦èªå·±å»å°è£
ä¸ä¸ªé«æ§è½çæä»¶ IO å·¥å
·ç±»ï¼æ¬æå°ä¼è§£æ Java IO 䏿¶åå°çå个类ï¼ä»¥å讲解å¦ä½æ£ç¡®ã髿å°ä½¿ç¨å®ä»¬ã
## BIO NIO å AIO çåºå«
æä»¬ä¼ä»¥ä¸ä¸ªç»å
¸ç**ç§å¼æ°´**çä¾åéä¿å°è®²è§£å®ä»¬ä¹é´çåºå«
| ç±»å | ç§å¼æ°´ |
| :--: | :----------------------------------------------------------: |
| BIO | ä¸ç´çæµçæä¸ªæ°´å£¶ï¼è¯¥æ°´å£¶ç§å¼æ°´ååçæµä¸ä¸ä¸ªæ°´å£¶ |
| NIO | æ¯é䏿®µæ¶é´å°±ççæææ°´å£¶çç¶æï¼åªä¸ªæ°´å£¶ç§å¼æ°´å°±å»å¤çåªä¸ªæ°´å£¶ |
| AIO | ä¸ç¨çæµæ°´å£¶ï¼æ¯ä¸ªæ°´å£¶ç§å¼æ°´åé½ä¼ä¸»å¨éç¥çº¿ç¨è¯´ï¼âæçæ°´ç§å¼äºï¼æ¥å¤çæå§â |
**BIO (忥é»å¡ I/O)**
è¿éå设ä¸ä¸ªç§å¼æ°´çåºæ¯ï¼æä¸ææ°´å£¶å¨ç§å¼æ°´ï¼BIOç工使¨¡å¼å°±æ¯ï¼ å°è è**ä¸ç´çççè¿ä¸ªæ°´å£¶ï¼ç´å°è¿ä¸ªæ°´å£¶ç§å¼ï¼æå»å¤çä¸ä¸ä¸ªæ°´å£¶**ã线ç¨å¨çå¾
水壶ç§å¼çæ¶é´æ®µä»ä¹é½æ²¡æåã
**NIOï¼åæ¥éé»å¡ I/Oï¼**
è¿æ¿ç§å¼æ°´æ¥è¯´ï¼NIOçåæ³æ¯**å°è èä¸è¾¹ç©çææºï¼æ¯é䏿®µæ¶é´å°±çä¸çæ¯ä¸ªæ°´å£¶çç¶æ**ï¼ççæ¯å¦ææ°´å£¶çç¶æåçäºæ¹åï¼å¦ææä¸ªæ°´å£¶ç§å¼äºï¼å¯ä»¥å
å¤çé£ä¸ªæ°´å£¶ï¼ç¶åç»§ç»ç©ææºï¼ç»§ç»é䏿®µæ¶é´åççæ¯ä¸ªæ°´å£¶çç¶æã
**AIO ï¼å¼æ¥éé»å¡ I/Oï¼**
å°è èè§å¾æ¯é䏿®µæ¶é´å°±å»çä¸ç水壶太费å²äºï¼äºæ¯è´ä¹°äºä¸æ¹ç§å¼æ°´æ¶å¯ä»¥**ååå**çæ°´å£¶ï¼äºæ¯å¼å§ç§æ°´åï¼å°è èå°±ç´æ¥å»å®¢å
ç©ææºäºï¼æ°´ç§å¼æ¶ï¼å°±ååºâååâçå声ï¼**éç¥å°è èæ¥å
³ææ°´å£¶**ã
## ä»ä¹æ¯æµ
ç¥è¯ç§æ®ï¼æä»¬ç¥éä»»ä½ä¸ä¸ªæä»¶é½æ¯ä»¥**äºè¿å¶**å½¢å¼åå¨äºè®¾å¤ä¸ï¼è®¡ç®æºå°±åªæ `0` å `1`ï¼ä½ è½çè§çä¸è¥¿å
¨é¨é½æ¯ç±è¿ä¸¤ä¸ªæ°åç»æï¼ä½ çè¿ç¯æç« æ¶ï¼è¿ç¯æç« 乿¯ç±01ç»æï¼åªä¸è¿è¿äºäºè¿å¶ä¸²ç»è¿åç§è½¬æ¢æ¼åæä¸ä¸ªä¸ªæåãä¸å¼ å¼ å¾çè·ç¶å±å¹ä¸ã
è**æµ**å°±æ¯å°è¿äºäºè¿å¶ä¸²å¨åç§è®¾å¤ä¹é´è¿è¡ä¼ è¾ï¼å¦æä½ è§å¾æäºæ½è±¡ï¼æä¸¾ä¸ªä¾åå°±ä¼å¥½çè§£ä¸äºï¼
> ä¸å¾æ¯ä¸å¼ å¾çï¼å®ç±01ä¸²ç»æï¼æä»¬å¯ä»¥éè¿ç¨åºæä¸å¼ å¾çæ·è´å°ä¸ä¸ªæä»¶å¤¹ä¸ï¼
>
> æå¾ç转åæäºè¿å¶æ°æ®éï¼ææ°æ®ä¸ç¹ä¸ç¹å°ä¼ éå°æä»¶å¤¹ä¸ , ç±»ä¼¼äºæ°´çæµå¨ , è¿æ ·æ´ä½çæ°æ®å°±æ¯ä¸ä¸ªæ°æ®æµ

IO æµè¯»åæ°æ®çç¹ç¹ï¼
- **顺åºè¯»å**ãè¯»åæ°æ®æ¶ï¼å¤§é¨åæ
åµä¸é½æ¯æç
§é¡ºåºè¯»åï¼è¯»åæ¶ä»æä»¶å¼å¤´ç第ä¸ä¸ªåèå°æåä¸ä¸ªåèï¼ååºæ¶ä¹æ¯ä¹å¦æ¤ï¼RandomAccessFile å¯ä»¥å®ç°éæºè¯»åï¼
- **åèæ°ç»**ãè¯»åæ°æ®æ¶æ¬è´¨ä¸é½æ¯å¯¹åèæ°ç»å读ååååºæä½ï¼å³ä½¿æ¯å符æµï¼ä¹æ¯å¨åèæµåºç¡ä¸è½¬å为ä¸ä¸ªä¸ªåç¬¦ï¼æä»¥åèæ°ç»æ¯ IO æµè¯»åæ°æ®çæ¬è´¨ã
## æµçåç±»
æ ¹æ®**æ°æ®æµå**ä¸ååç±»ï¼è¾å
¥æµ å è¾åºæµ
- **è¾å
¥æµ**ï¼ä»ç£çæè
å
¶å®è®¾å¤ä¸å°æ°æ®è¾å
¥å°è¿ç¨ä¸
- **è¾åºæµ**ï¼å°è¿ç¨ä¸çæ°æ®è¾åºå°ç£çæå
¶å®è®¾å¤ä¸ä¿å

å¾ç¤ºä¸ç硬çåªæ¯å
¶ä¸ä¸ç§è®¾å¤ï¼è¿æé常å¤ç设å¤é½å¯ä»¥åºç¨å¨IOæµä¸ï¼ä¾å¦ï¼æå°æºã硬çãæ¾ç¤ºå¨ãææºÂ·Â·Â·Â·Â·Â·
æ ¹æ®**å¤çæ°æ®çåºæ¬åä½**ä¸ååç±»ï¼åèæµ å å符æµ
- åèæµï¼ä»¥**åèï¼8 bitï¼**为åä½åæ°æ®çä¼ è¾
- å符æµï¼ä»¥**å符**为åä½ï¼1å符 = 2åèï¼åæ°æ®çä¼ è¾
> å符æµçæ¬è´¨ä¹æ¯éè¿åèæµè¯»åï¼Java ä¸çå符éç¨ Unicode æ åï¼å¨è¯»ååè¾åºçè¿ç¨ä¸ï¼éè¿ä»¥å符为åä½ï¼æ¥æ¾å¯¹åºçç 表å°åè转æ¢ä¸ºå¯¹åºçå符ã
é¢å¯¹åèæµåå符æµï¼å¾å¤è¯»è
齿çæï¼**ä»ä¹æ¶åéè¦ç¨åèæµï¼ä»ä¹æ¶ååè¦ç¨å符æµï¼**
æè¿éåä¸ä¸ªç®åçæ¦æ¬ï¼ä½ å¯ä»¥æç
§è¿ä¸ªæ åå»ä½¿ç¨ï¼
å符æµåªé对åç¬¦æ°æ®è¿è¡ä¼ è¾ï¼æä»¥å¦ææ¯**ææ¬æ°æ®**ï¼ä¼å
**éç¨å符æµ**ä¼ è¾ï¼é¤æ¤ä¹å¤ï¼å
¶å®ç±»åçæ°æ®ï¼å¾çãé³é¢çï¼ï¼æå¥½è¿æ¯ä»¥**åèæµ**ä¼ è¾ã
æ ¹æ®è¿ä¸¤ç§ä¸åçåç±»ï¼æä»¬å°±å¯ä»¥ååºä¸é¢è¿ä¸ªè¡¨æ ¼ï¼éé¢å
å«äº IO ä¸ææ ¸å¿ç 4 ä¸ªé¡¶å±æ½è±¡ç±»ï¼
| æ°æ®æµå / æ°æ®ç±»å | åèæµ | åç¬¦æµ |
| ------------------- | ------------ | ------ |
| è¾å
¥æµ | InputStream | Reader |
| è¾åºæµ | OutputStream | Writer |
ç°å¨ç IO æ¯ä¸æ¯æä¸äºæè·¯äºï¼ä¸ä¼è§å¾å¾æ··ä¹±äºï¼æä»¬æ¥çè¿å个类ä¸çæææåã

[æ¥èªäº cxuan ç ãJavaåºç¡æ ¸å¿æ»ç»ã]
çå°è¿ä¹å¤çç±»æ¯ä¸æ¯åå¼å§è§å¾æ··ä¹±äºï¼ä¸è¦æ
ï¼åèæµåå符æµä¸çè¾å
¥æµåè¾åºæµå¤§é¨å齿¯ä¸ä¸å¯¹åºçï¼æäºä¸é¢çè¡¨æ ¼æ¯æï¼æä»¬ä¸éè¦åæ
å¿çè§æä¸ªç±»ä¼æµé¼çæ
åµäºã
çå° `Stream` å°±ç¥éæ¯**åèæµ**ï¼çå° `Reader / Writer` å°±ç¥éæ¯**å符æµ**ã
è¿éè¿è¦é¢å¤è¡¥å
ä¸ç¹ï¼Java IO æä¾äº**åèæµè½¬æ¢ä¸ºå符æµç转æ¢ç±»**ï¼ç§°ä¸ºè½¬æ¢æµã
| è½¬æ¢æµ / æ°æ®ç±»å | åèæµä¸å符æµä¹é´çè½¬æ¢ |
| ------------------------ | ------------------------ |
| ï¼è¾å
¥ï¼åèæµ => åç¬¦æµ | InputStreamReader |
| ï¼è¾åºï¼åç¬¦æµ => åèæµ | OutputStreamWriter |
注æåèæµä¸å符æµä¹é´çè½¬æ¢æ¯æä¸¥æ ¼å®ä¹çï¼
- è¾å
¥æµï¼å¯ä»¥å°åèæµ => å符æµ
- è¾åºæµï¼å¯ä»¥å°åç¬¦æµ => åèæµ
为ä»ä¹å¨è¾å
¥æµä¸è½åç¬¦æµ => åèæµï¼è¾åºæµä¸è½åèæµ => å符æµï¼
> å¨åå¨è®¾å¤ä¸ï¼æææ°æ®é½æ¯ä»¥**åè**为åä½åå¨çï¼æä»¥**è¾å
¥å°å
åæ¶å¿
宿¯ä»¥åè为åä½è¾å
¥ï¼è¾åºå°åå¨è®¾å¤æ¶å¿
é¡»æ¯ä»¥åè为åä½è¾åº**ï¼åèæµææ¯è®¡ç®æºææ ¹æ¬çå卿¹å¼ï¼èåç¬¦æµæ¯å¨åèæµçåºç¡ä¸å¯¹æ°æ®è¿è¡è½¬æ¢ï¼è¾åºå符ï¼ä½æ¯ä¸ªåç¬¦ä¾æ§æ¯ä»¥åè为åä½åå¨çã
## èç¹æµåå¤çæµ
å¨è¿ééè¦é¢å¤æå
¥ä¸ä¸ªå°è讲解èç¹æµåå¤çæµã
- **èç¹æµ**ï¼èç¹æµæ¯**çæ£ä¼ è¾æ°æ®**çæµå¯¹è±¡ï¼ç¨äºåç¹å®çä¸ä¸ªå°æ¹ï¼èç¹ï¼è¯»åæ°æ®ï¼ç§°ä¸ºèç¹æµãä¾å¦ FileInputStream
- **å¤çæµ**ï¼å¤çæµæ¯**对èç¹æµçå°è£
**ï¼ä½¿ç¨å¤å±çå¤çæµè¯»åæ°æ®ï¼æ¬è´¨ä¸æ¯å©ç¨èç¹æµçåè½ï¼å¤å±çå¤çæµå¯ä»¥æä¾é¢å¤çåè½ãå¤çæµçåºç±»é½æ¯ä»¥ `Filter` å¼å¤´ã

ä¸å¾å° `ByteArrayInputStream` å°è£
æ `DataInputStream`ï¼å¯ä»¥å°è¾å
¥çåèæ°ç»è½¬æ¢ä¸ºå¯¹åºæ°æ®ç±»åçæ°æ®ãä¾å¦å¸æè¯»å
¥`int`ç±»åæ°æ®ï¼å°±ä¼ä»¥`2`个åè为åä½è½¬æ¢ä¸ºä¸ä¸ªæ°åã
## Java IO çæ ¸å¿ç±» File
Java æä¾äº Fileç±»ï¼å®æåè®¡ç®æºæä½ç³»ç»ä¸çæä»¶åç®å½ï¼éè¿è¯¥ç±»åªè½è®¿é®æä»¶åç®å½ï¼æ æ³è®¿é®å
容ã å®å
é¨ä¸»è¦æä¾äº `3` ç§æä½ï¼
- **è®¿é®æä»¶ç屿§**ï¼ç»å¯¹è·¯å¾ãç¸å¯¹è·¯å¾ãæä»¶å······
- **æä»¶æ£æµ**ï¼æ¯å¦æä»¶ãæ¯å¦ç®å½ãæä»¶æ¯å¦åå¨ãæä»¶ç读/å/æ§è¡æé······
- **æä½æä»¶**ï¼å建ç®å½ãå建æä»¶ãå é¤æä»¶Â·Â·Â·Â·Â·Â·
ä¸é¢ä¸¾ä¾çæä½é½æ¯å¨å¼åä¸é常常ç¨çï¼File ç±»è¿ä¸æ¢è¿äºæä½ï¼æ´å¤çæä½å¯ä»¥ç´æ¥å» API ææ¡£ä¸æ ¹æ®éæ±æ¥æ¾ã
è®¿é®æä»¶ç屿§ï¼
| API | åè½ |
| :----------------------: | :----------------------------------------------------: |
| String getAbsolutePath() | è¿å该æä»¶å¤äºç³»ç»ä¸çç»å¯¹è·¯å¾å |
| String getPath() | è¿å该æä»¶çç¸å¯¹è·¯å¾ï¼éå¸¸ä¸ new File() ä¼ å
¥çè·¯å¾ç¸å |
| String getName() | è¿å该æä»¶çæä»¶å |
æä»¶æ£æµï¼
| API | åè½ |
| :-------------------: | :-------------------------------: |
| boolean isFIle() | æ ¡éªè¯¥è·¯å¾æåæ¯å¦ä¸ä¸ªæä»¶ |
| boolean isDirectory() | æ ¡éªè¯¥è·¯å¾æåæ¯å¦ä¸ä¸ªç®å½ |
| boolean isExist() | æ ¡éªè¯¥è·¯å¾æåçæä»¶/ç®å½æ¯å¦åå¨ |
| boolean canWrite() | æ ¡éªè¯¥æä»¶æ¯å¦å¯å |
| boolean canRead() | æ ¡éªè¯¥æä»¶æ¯å¦å¯è¯» |
| boolean canExecute() | æ ¡éªè¯¥æä»¶/ç®å½æ¯å¦å¯ä»¥è¢«æ§è¡ |
æä½æä»¶ï¼
| API | åè½ |
| :-------------: | :----------------------------------------------------------: |
| mkdirs() | éå½å建å¤ä¸ªæä»¶å¤¹ï¼è·¯å¾ä¸é´æå¯è½æäºæä»¶å¤¹ä¸åå¨ |
| createNewFile() | åå»ºæ°æä»¶ï¼å®æ¯ä¸ä¸ªååæä½ï¼æä¸¤æ¥ï¼æ£æ¥æä»¶æ¯å¦åå¨ãåå»ºæ°æä»¶ |
| delete() | å 餿件æç®å½ï¼å é¤ç®å½æ¶å¿
é¡»ä¿è¯è¯¥ç®å½ä¸ºç©º |
**å¤äºè§£ä¸äº**
æä»¶ç读/å/æ§è¡æéï¼å¨ `Windows` ä¸é常表ç°ä¸åºæ¥ï¼èå¨ `Linux` ä¸å¯ä»¥å¾å¥½å°ä½ç°è¿ä¸ç¹ï¼åå æ¯ `Linux` æä¸¥æ ¼çç¨æ·æéåç»ï¼ä¸ååç»ä¸çç¨æ·å¯¹æä»¶æä¸åçæä½æéï¼æä»¥è¿äºæ¹æ³å¨ `Linux` ä¸ä¼æ¯å¨ `Windows` 䏿´å¥½çè§£ãä¸å¾æ¯ redis æä»¶å¤¹ä¸çä¸äºæä»¶ç详ç»ä¿¡æ¯ï¼è¢«çº¢æ¡æ æ³¨çæ¯ä¸åç¨æ·çæ§è¡æéï¼
- rï¼Readï¼ï¼ä»£è¡¨è¯¥æä»¶å¯ä»¥è¢«å½åç¨æ·è¯»ï¼æä½æéçåºå·æ¯ `4`
- wï¼Writeï¼ï¼ä»£è¡¨è¯¥æä»¶å¯ä»¥è¢«å½åç¨æ·åï¼æä½æéçåºå·æ¯ `2`
- xï¼Executeï¼ï¼è¯¥æä»¶å¯ä»¥è¢«å½åç¨æ·æ§è¡ï¼æä½æéçåºå·æ¯ `1`

`root root` åå«ä»£è¡¨ï¼**å½åæä»¶çææè
**ï¼**å½åæä»¶æå±çç¨æ·åç»**ãLinux 䏿件çæä½æéå为ä¸ç§ç¨æ·ï¼
- **æä»¶ææè
**ï¼æ¥æçæéæ¯çº¢æ¡ä¸ç**åä¸ä¸ªåæ¯**ï¼`-`代表没ææä¸ªæé
- **æä»¶æå¨ç»çææç¨æ·**ï¼æ¥æçæéæ¯çº¢æ¡ä¸ç**ä¸é´ä¸ä¸ªåæ¯**
- **å
¶å®ç»çææç¨æ·**ï¼æ¥æçæéæ¯çº¢æ¡ä¸ç**æåä¸ä¸ªåæ¯**
## Java IO æµå¯¹è±¡
å顾æµçåç±»æ2ç§ï¼
- æ ¹æ®**æ°æ®æµå**å为è¾å
¥æµåè¾åºæµ
- æ ¹æ®**æ°æ®ç±»å**å为åèæµåå符æµ
æä»¥ï¼æ¬å°èå°ä»¥åèæµåå符æµä½ä¸ºä¸»è¦åå²ç¹ï¼å¨å
¶å
é¨åç»å为è¾å
¥æµåè¾åºæµè¿è¡è®²è§£ã

### åèæµå¯¹è±¡
åèæµå¯¹è±¡å¤§é¨åè¾å
¥æµåè¾åºæµé½æ¯**æåæå¯¹å°åºç°**ï¼æä»¥å¦ä¹ çæ¶åå¯ä»¥å°è¾å
¥æµåè¾åºæµä¸ä¸å¯¹åºçæµå¯¹è±¡å
³èèµ·æ¥ï¼è¾å
¥æµåè¾åºæµåªæ¯**æ°æ®æµå**ä¸åï¼è**å¤çæ°æ®çæ¹å¼**å¯ä»¥æ¯ç¸åçã
注æä¸è¦è®¤ä¸ºç¨ä»ä¹æµè¯»å
¥æ°æ®ï¼å°±éè¦ç¨å¯¹åºçæµååºæ°æ®ï¼å¨ Java 䏿²¡æè¿ä¹è§å®ï¼ä¸å¾åªæ¯å个对象ä¹é´çä¸ä¸ªå¯¹åºå
³ç³»ï¼**䏿¯ä¸¤ä¸ªç±»ä½¿ç¨æ¶å¿
须强å¶å
³è使ç¨**ã
> ä¸é¢æé常å¤çç±»ï¼æä¼ä»ç»åºç±»çæ¹æ³ï¼äºè§£è¿äºæ¹æ³æ¯**é常æå¿
è¦**çï¼åç±»çåè½åºäºç¶ç±»å»æ©å±ï¼åªæçæ£äºè§£ç¶ç±»å¨åä»ä¹ï¼å¦ä¹ åç±»çææ¬å°±ä¼ä¸éã

#### InputStream
InputStream æ¯åèè¾å
¥æµçæ½è±¡åºç±»ï¼æä¾äºéç¨çè¯»æ¹æ³ï¼è®©åç±»ä½¿ç¨æéåå®ä»¬ãä¸é¢æ¯ InputStream 常ç¨çéè¦çæ¹æ³ã
| éè¦æ¹æ³ | åè½ |
| :-----------------------------------------: | :---------------------------------------------------: |
| public abstract int read() | ä»è¾å
¥æµä¸è¯»åä¸ä¸ä¸ªåèï¼è¯»å°å°¾é¨æ¶è¿å -1 |
| public int read(byte b[]) | ä»è¾å
¥æµä¸è¯»åé¿åº¦ä¸º b.length 个åèæ¾å
¥åèæ°ç» b ä¸ |
| public int read(byte b[], int off, int len) | ä»è¾å
¥æµä¸è¯»åæå®èå´çåèæ°æ®æ¾å
¥åèæ°ç» b ä¸ |
| public void close() | å
³éæ¤è¾å
¥æµå¹¶éæ¾ä¸è¯¥è¾å
¥æµç¸å
³çææèµæº |
è¿æå
¶å®ä¸äºä¸å¤ªå¸¸ç¨çæ¹æ³ï¼æä¹ååºæ¥äºã
| å
¶å®æ¹æ³ | åè½ |
| :------------------------------------------: | :----------------------------------------------------------: |
| public long skip(long n) | è·³è¿æ¥ä¸æ¥ç n 个åèï¼è¿åå®é
ä¸è·³è¿çåèæ° |
| public long available() | è¿åä¸ä¸æ¬¡å¯è¯»åï¼è·³è¿ï¼ä¸ä¸ä¼è¢«æ¹æ³é»å¡çåèæ°çä¼°è®¡å¼ |
| public synchronized void mark(int readlimit) | æ è®°æ¤è¾å
¥æµçå½åä½ç½®ï¼å¯¹ reset() æ¹æ³çåç»è°ç¨å°ä¼éæ°å®ä½å¨ mark() æ è®°çä½ç½®ï¼å¯ä»¥éæ°è¯»åç¸åçåè |
| public boolean markSupported() | å¤æè¯¥è¾å
¥æµæ¯å¦æ¯æ mark() å reset() æ¹æ³ï¼å³è½å¦éå¤è¯»ååè |
| public synchronized void reset() | å°æµçä½ç½®éæ°å®ä½å¨æå䏿¬¡è°ç¨ mark() æ¹æ³æ¶çä½ç½® |

**ï¼1ï¼ByteArrayInputStream**
ByteArrayInputStream å
é¨å
å«ä¸ä¸ª `buf` åèæ°ç»ç¼å²åºï¼è¯¥ç¼å²åºå¯ä»¥ä»æµä¸è¯»åçåèæ°ï¼ä½¿ç¨ `pos` æéæå读åä¸ä¸ä¸ªåèç䏿 ä½ç½®ï¼å
é¨è¿ç»´æ¤äºä¸ä¸ª`count` 屿§ï¼ä»£è¡¨è½å¤è¯»å `count` 个åèã

> å¿
é¡»ä¿è¯ pos ä¸¥æ ¼å°äº countï¼è count ä¸¥æ ¼å°äº buf.length æ¶ï¼æè½å¤ä»ç¼å²åºä¸è¯»åæ°æ®
**ï¼2ï¼FileInputStream**
æä»¶è¾å
¥æµï¼ä»æä»¶ä¸è¯»å
¥åèï¼é常对æä»¶çæ·è´ãç§»å¨çæä½ï¼å¯ä»¥ä½¿ç¨è¯¥è¾å
¥æµææä»¶çåè读å
¥å
åä¸ï¼ç¶ååå©ç¨è¾åºæµè¾åºå°æå®çä½ç½®ä¸ã
**ï¼3ï¼PipedInputStream**
管éè¾å
¥æµï¼å®ä¸ PipedOutputStream æå¯¹åºç°ï¼å¯ä»¥å®ç°å¤çº¿ç¨ä¸ç**管ééä¿¡**ãPipedOutputStream 䏿å®ä¸ç¹å®ç PipedInputStream è¿æ¥ï¼PipedInputStream ä¹éè¦æå®ç¹å®ç PipedOutputStream è¿æ¥ï¼ä¹åè¾åºæµä¸æå°å¾è¾å
¥æµç `buffer` ç¼å²åºåæ°æ®ï¼èè¾å
¥æµå¯ä»¥ä»ç¼å²åºä¸è¯»åæ°æ®ã
**ï¼4ï¼ObjectInputStream**
对象è¾å
¥æµï¼ç¨äºå¯¹è±¡çååºååï¼å°è¯»å
¥çåèæ°æ®ååºåå为ä¸ä¸ªå¯¹è±¡ï¼å®ç°å¯¹è±¡çæä¹
ååå¨ã
**ï¼5ï¼PushBackInputStream**
宿¯ FilterInputStream çåç±»ï¼æ¯ä¸ä¸ª**å¤çæµ**ï¼å®å
é¨ç»´æ¤äºä¸ä¸ªç¼å²æ°ç»`buf`ã
- å¨è¯»å
¥åèçè¿ç¨ä¸å¯ä»¥å°**读åå°çåèæ°æ®åéç»ç¼å²åºä¸ä¿å**ï¼ä¸æ¬¡å¯ä»¥å次ä»ç¼å²åºä¸è¯»åºè¯¥åèæ°æ®ãæä»¥**PushBackInputStream å
è®¸å¤æ¬¡è¯»åè¾å
¥æµçåèæ°æ®**ï¼åªè¦å°è¯»å°çåèæ¾åç¼å²åºå³å¯ã

éè¦æ³¨æçæ¯å¦æåæ¨åèæ¶ï¼å¦æç¼å²åºå·²æ»¡ï¼ä¼æåº `IOException` å¼å¸¸ã
å®çåºç¨åºæ¯ï¼**å¯¹æ°æ®è¿è¡åç±»è§æ´**ã
åå¦ä¸ä¸ªæä»¶ä¸åå¨äº**æ°å**å**忝**两ç§ç±»åçæ°æ®ï¼æä»¬éè¦å°å®ä»¬äº¤ç»ä¸¤ç§çº¿ç¨åèªå»æ¶éèªå·±è´è´£çæ°æ®ï¼å¦æéç¨ä¼ ç»çåæ³ï¼æææçæ°æ®å
¨é¨è¯»å
¥å
åä¸ï¼åå°æ°æ®è¿è¡å离ï¼é¢å¯¹å¤§æä»¶çæ
åµä¸ï¼ä¾å¦**1Gã2G**ï¼ä¼ ç»çè¾å
¥æµå¨è¯»å
¥æ°ç»åï¼**ç±äºæ²¡æç¼å²åºï¼åªè½å¯¹æ°æ®è¿è¡æå¼ï¼è¿æ ·æ¯ä¸ªçº¿ç¨é½è¦è¯»ä¸éæä»¶**ã
ä½¿ç¨ PushBackInputStream å¯ä»¥è®©ä¸ä¸ªä¸é¨ç线ç¨**读å**æä»¶ï¼å¤éä¸åç线ç¨è¯»åå符ï¼
- ç¬¬ä¸æ¬¡è¯»åç¼å²åºçæ°æ®ï¼å¤æè¯¥æ°æ®ç±åªäºçº¿ç¨è¯»å
- åéæ°æ®ï¼å¤é对åºç线ç¨è¯»åæ°æ®
- éå¤å两æ¥
- å
³éè¾å
¥æµ
å°è¿éï¼ä½ æ¯å¦ä¼æ³å° `AQS` ç `Condition` çå¾
éåï¼å¤ä¸ªçº¿ç¨å¯ä»¥å¨ä¸åçæ¡ä»¶ä¸çå¾
被å¤éã
**ï¼6ï¼BufferedInputStream**
ç¼å²æµï¼å®æ¯ä¸ç§**å¤çæµ**ï¼å¯¹èç¹æµè¿è¡å°è£
å¹¶å¢å¼ºï¼å
¶å
鍿¥æä¸ä¸ª `buffer` ç¼å²åºï¼ç¨äºç¼åææè¯»å
¥çåèï¼**å½ç¼å²åºæ»¡æ¶ï¼æä¼å°ææåèåéç»å®¢æ·ç«¯è¯»å**ï¼è䏿¯æ¯æ¬¡é½åªåéä¸é¨åæ°æ®ï¼æé«äºæçã
**ï¼7ï¼DataInputStream**
æ°æ®è¾å
¥æµï¼å®åæ ·æ¯ä¸ç§**å¤çæµ**ï¼å¯¹èç¹æµè¿è¡å°è£
åï¼è½å¤å¨å
é¨å¯¹è¯»å
¥çåè转æ¢ä¸ºå¯¹åºç Java åºæ¬æ°æ®ç±»åã
**ï¼8ï¼SequenceInputStream**
å°ä¸¤ä¸ªæå¤ä¸ªè¾å
¥æµç使¯ä¸ä¸ªè¾å
¥æµä¾æ¬¡è¯»åï¼è¯¥ç±»çåå¨ä¸å¦å¹¶ä¸å½±åæ´ä¸ª IO çæï¼å¨ç¨åºä¸ä¹è½å¤åå°è¿ç§ææ
**~~ï¼9ï¼StringBufferInputStream~~**
å°åç¬¦ä¸²ä¸æ¯ä¸ªå符çä½ 8 ä½è½¬æ¢ä¸ºåè读å
¥å°åèæ°ç»ä¸ï¼ç®åå·²è¿æ
**InputStream æ»ç»ï¼**
- InputStream æ¯ææè¾å
¥åèæµç**æ½è±¡åºç±»**
- ByteArrayInputStream å FileInputStream æ¯ä¸¤ç§åºæ¬çèç¹æµï¼ä»ä»¬åå«ä»**åèæ°ç»** å **æ¬å°æä»¶**ä¸è¯»åæ°æ®
- DataInputStreamãBufferedInputStream å PushBackInputStream 齿¯**å¤çæµ**ï¼å¯¹åºæ¬çèç¹æµè¿è¡å°è£
å¹¶å¢å¼º
- PipiedInputStream ç¨äº**å¤çº¿ç¨éä¿¡**ï¼å¯ä»¥ä¸å
¶å®çº¿ç¨å
¬ç¨ä¸ä¸ªç®¡éï¼è¯»å管éä¸çæ°æ®ã
- ObjectInputStream ç¨äº**对象çååºåå**ï¼å°å¯¹è±¡çåèæ°æ®è¯»å
¥å
åä¸ï¼éè¿è¯¥æµå¯¹è±¡å¯ä»¥å°åèæ°æ®è½¬æ¢æå¯¹åºç对象
#### OutputStream
OutputStream æ¯åèè¾åºæµçæ½è±¡åºç±»ï¼æä¾äºéç¨çåæ¹æ³ï¼è®©ç»§æ¿çåç±»éååå¤ç¨ã
| æ¹æ³ | åè½ |
| :-------------------------------------------- | ------------------------------------------------------------ |
| public abstract void write(int b) | å°æå®çåèååºå°è¾åºæµï¼åå
¥çåèæ¯åæ° b çä½ 8 ä½ |
| public void write(byte b[]) | å°æå®åèæ°ç»ä¸çææåèåå
¥å°è¾åºæµå½ä¸ |
| public void write(byte b[], int off, int len) | æå®åå
¥çèµ·å§ä½ç½® offerï¼åèæ°ä¸º len çåèæ°ç»åå
¥å°è¾åºæµå½ä¸ |
| public void flush() | å·æ°æ¤è¾åºæµï¼å¹¶å¼ºå¶ååºææç¼å²çè¾åºåèå°æå®ä½ç½®ï¼æ¯æ¬¡åå®é½è¦è°ç¨ |
| public void close() | å
³éæ¤è¾åºæµå¹¶éæ¾ä¸æ¤æµå
³èçææç³»ç»èµæº |

OutputStream ä¸å¤§å¤æ°çç±»å InputStream æ¯å¯¹åºçï¼åªä¸è¿æ°æ®çæµåä¸åèå·²ãä»ä¸é¢çå¾å¯ä»¥çåºï¼
- OutputStream æ¯ææè¾åºåèæµç**æ½è±¡åºç±»**
- ByteArrayOutputStream å FileOutputStream æ¯ä¸¤ç§åºæ¬çèç¹æµï¼å®ä»¬åå«å**åèæ°ç»**å**æ¬å°æä»¶**ååºæ°æ®
- DataOutputStreamãBufferedOutputStream æ¯**å¤çæµ**ï¼åè
å¯ä»¥å°**åèæ°æ®è½¬æ¢æåºæ¬æ°æ®ç±»å**ååºå°æä»¶ä¸ï¼åè
æ¯ç¼å²åèæ°ç»ï¼åªæå¨ç¼å²åºæ»¡æ¶ï¼æä¼å°ææçåèååºå°ç®çå°ï¼**åå°äº IO 次æ°**ã
- PipedOutputStream ç¨äº**å¤çº¿ç¨éä¿¡**ï¼å¯ä»¥åå
¶å®çº¿ç¨å
±ç¨ä¸ä¸ªç®¡éï¼å管éä¸åå
¥æ°æ®
- ObjectOutputStream ç¨äºå¯¹è±¡ç**åºåå**ï¼å°å¯¹è±¡è½¬æ¢æåèæ°ç»åï¼å°ææçåèé½åå
¥å°æå®ä½ç½®ä¸
- PrintStream å¨ OutputStream åºç¡ä¹ä¸æä¾äºå¢å¼ºçåè½ï¼å³**å¯ä»¥æ¹ä¾¿å°è¾åºåç§ç±»åçæ°æ®**ï¼èä¸ä»
éäºbyteåï¼çæ ¼å¼å表示形å¼ï¼ä¸ PrintStream çæ¹æ³ä»ä¸æåº IOEceptionï¼å
¶åçæ¯**ååºæ¶å°åä¸ªæ°æ®ç±»åçæ°æ®ç»ä¸è½¬æ¢ä¸º String ç±»å**ï¼æä¼å¨è®²è§£å®
### å符æµå¯¹è±¡
å符æµå¯¹è±¡ä¹ä¼æå¯¹åºå
³ç³»ï¼å¤§å¤æ°çç±»å¯ä»¥è®¤ä¸ºæ¯**æä½çæ°æ®ä»åèæ°ç»å为å符**ï¼ç±»çåè½ååèæµå¯¹è±¡æ¯ç¸ä¼¼çã
> å符è¾å
¥æµååèè¾å
¥æµçç»æé常ç¸ä¼¼ï¼å符è¾å
¥æµæ¯å¯¹åèè¾å
¥æµç**ä¸å±è½¬æ¢**ï¼æææä»¶çåå¨é½æ¯**åèçåå¨**ï¼å¨ç£çä¸ä¿çç䏿¯æä»¶çå符ï¼èæ¯å
æå符ç¼ç æåèï¼åä¿åå°æä»¶ä¸ãå¨è¯»åæä»¶æ¶ï¼è¯»å
¥ç乿¯ä¸ä¸ªä¸ä¸ªåèç»æçåèåºåï¼è Java èææºéè¿å°åèåºåï¼æç
§2个åè为åä½è½¬æ¢ä¸º Unicode å符ï¼å®ç°åèå°åç¬¦çæ å°ã

#### Reader
Reader æ¯å符è¾å
¥æµçæ½è±¡åºç±»ï¼å®å
é¨çéè¦æ¹æ³å¦ä¸æç¤ºã
| éè¦æ¹æ³ | æ¹æ³åè½ |
| ------------------------------------------------------- | ---------------------------------- |
| public int read(java.nio.CharBuffer target) | å°è¯»å
¥çå符åå
¥æå®çå符ç¼å²åºä¸ |
| public int read() | 读åä¸ä¸ªå符 |
| public int read(char cbuf[]) | 读å
¥å符æ¾å
¥æ´ä¸ªå符æ°ç»ä¸ |
| abstract public int read(char cbuf[], int off, int len) | å°å符读å
¥å符æ°ç»ä¸çæå®èå´ä¸ |
è¿æå
¶å®ä¸äºé¢å¤çæ¹æ³ï¼ä¸åèè¾å
¥æµåºç±»æä¾çæ¹æ³æ¯ç¸åçï¼åªæ¯ä½ç¨ç对象ä¸åæ¯åèï¼èæ¯å符ã

- Reader æ¯ææå符è¾å
¥æµç**æ½è±¡åºç±»**
- CharArrayReader å StringReader æ¯ä¸¤ç§åºæ¬çèç¹æµï¼å®ä»¬åå«ä»è¯»å **å符æ°ç»** å **å符串** æ°æ®ï¼StringReader å
鍿¯ä¸ä¸ª `String` åéå¼ï¼éè¿éå该åéçå符ï¼å®ç°è¯»åå符串ï¼**æ¬è´¨ä¸ä¹æ¯å¨è¯»åå符æ°ç»**
- PipedReader ç¨äºå¤çº¿ç¨ä¸çéä¿¡ï¼ä»å
±ç¨å°ç®¡éä¸è¯»ååç¬¦æ°æ®
- BufferedReader æ¯å符è¾å
¥**ç¼å²æµ**ï¼å°è¯»å
¥çæ°æ®æ¾å
¥å符ç¼å²åºä¸ï¼**å®ç°é«æå°è¯»åå符**
- InputStreamReader æ¯ä¸ç§**è½¬æ¢æµ**ï¼å¯ä»¥å®ç°ä»åèæµè½¬æ¢ä¸ºå符æµï¼å°åèæ°æ®è½¬æ¢ä¸ºå符
#### Writer
Reader æ¯å符è¾åºæµçæ½è±¡åºç±»ï¼å®å
é¨çéè¦æ¹æ³å¦ä¸æç¤ºã
| éè¦æ¹æ³ | æ¹æ³åè½ |
| --------------------------------------------------------- | ------------------------------------------------------------ |
| public void write(char cbuf[]) | å° cbuf å符æ°ç»ååºå°è¾åºæµ |
| abstract public void write(char cbuf[], int off, int len) | å°æå®èå´ç cbuf å符æ°ç»ååºå°è¾åºæµ |
| public void write(String str) | å°å符串 str ååºå°è¾åºæµï¼str å
é¨ä¹æ¯å符æ°ç» |
| public void write(String str, int off, int len) | å°å符串 str çæä¸é¨åååºå°è¾åºæµ |
| abstract public void flush() | å·æ°ï¼å¦ææ°æ®ä¿åå¨ç¼å²åºï¼è°ç¨è¯¥æ¹æ³æä¼çæ£ååºå°æå®ä½ç½® |
| abstract public void close() | å
³éæµå¯¹è±¡ï¼æ¯æ¬¡ IO æ§è¡å®æ¯åé½éè¦å
³éæµå¯¹è±¡ï¼éæ¾ç³»ç»èµæº |

- Writer æ¯ææçè¾åºå符æµçæ½è±¡åºç±»
- **CharArrayWriterãStringWriter æ¯ä¸¤ç§åºæ¬çèç¹æµï¼å®ä»¬åå«åChar æ°ç»ãå符串ä¸åå
¥æ°æ®ã**StringWriter å
é¨ä¿åäº StringBuffer 对象ï¼å¯ä»¥å®ç°å符串ç卿å¢é¿
- PipedWriter å¯ä»¥åå
±ç¨ç管éä¸**åå
¥åç¬¦æ°æ®**ï¼ç»å
¶å®çº¿ç¨è¯»åã
- **BufferedWriter** æ¯**ç¼å²è¾åºæµ**ï¼å¯ä»¥å°ååºçæ°æ®ç¼åèµ·æ¥ï¼ç¼å²åºæ»¡æ¶åè°ç¨ flush() ååºæ°æ®ï¼**åå° IO 次æ°**ã
- PrintWriter å PrintStream 类似ï¼åè½å使ç¨ä¹é常ç¸ä¼¼ï¼**åªæ¯ååºçæ°æ®æ¯å符è䏿¯åè**ã
- **OutputStreamWriter** å°**å符æµè½¬æ¢ä¸ºåèæµ**ï¼å°å符ååºå°æå®ä½ç½®
## åèæµä¸å符æµç转æ¢
ä»ä»»ä½å°æ¹ææ°æ®è¯»å
¥å°å
å齿¯å
以**åèæµ**å½¢å¼è¯»åï¼å³ä½¿æ¯ä½¿ç¨å符æµå»è¯»åæ°æ®ï¼ä¾ç¶æç«ï¼å ä¸ºæ°æ®æ°¸è¿æ¯ä»¥åèçå½¢å¼åå¨äºäºèç½å硬件设å¤ä¸ï¼åç¬¦æµæ¯éè¿**å符é**çæ å°ï¼æè½å¤å°åè转æ¢ä¸ºå符ã
æä»¥ Java æä¾äºä¸¤ç§è½¬æ¢æµï¼
- InputStreamReaderï¼ä»**åèæµè½¬æ¢ä¸ºå符æµ**ï¼å°åèæ°æ®è½¬æ¢ä¸ºåç¬¦æ°æ®è¯»å
¥å°å
å
- OutputStreamWriterï¼ä»**å符æµè½¬æ¢ä¸ºåèæµ**ï¼å°åç¬¦æ°æ®è½¬æ¢ä¸ºåèæ°æ®ååºå°æå®ä½ç½®
> äºè§£äº Java ä¼ ç»ç BIO ä¸å符æµååèæµçä¸»è¦æåä¹åï¼è³å°è¦ææ¡ä»¥ä¸ä¸¤ä¸ªå
³é®ç¹ï¼
>
> ï¼1ï¼ä¼ ç»ç BIO æ¯ä»¥`æµ`ä¸ºåºæ¬åä½å¤çæ°æ®çï¼æ³è±¡ææ°´æµï¼ä¸ç¹ç¹å°ä¼ è¾åèæ°æ®ï¼IO æµä¼ è¾çè¿ç¨æ°¸è¿æ¯ä»¥`åè`å½¢å¼ä¼ è¾ã
>
> ï¼2ï¼åèæµåå符æµçåºå«å¨äºæä½çæ°æ®åä½ä¸ç¸åï¼åç¬¦æµæ¯éè¿å°åèæ°æ®éè¿åç¬¦éæ å°æå¯¹åºçå符ï¼åç¬¦æµæ¬è´¨ä¸ä¹æ¯åèæµã
æ¥ä¸æ¥æä»¬åç»§ç»å¦ä¹ NIO ç¥è¯ï¼NIO æ¯å½ä¸é常ç«ççä¸ç§ IO 工使¹å¼ï¼å®è½å¤è§£å³ä¼ ç» BIO ççç¹ï¼**é»å¡**ã
- BIO 妿éå° IO é»å¡æ¶ï¼çº¿ç¨å°ä¼è¢«æèµ·ï¼ç´å° IO 宿åæå¤é线ç¨ï¼çº¿ç¨åæ¢å¸¦æ¥äºé¢å¤çå¼éã
- BIO 䏿¯ä¸ª IO é½éè¦æå¯¹åºçä¸ä¸ªçº¿ç¨å»ä¸é¨å¤ç该次 IO 请æ±ï¼ä¼è®©æå¡å¨çååè¿
éæé«ã
æä»¬å¸æåå°çæ¯**å½çº¿ç¨çå¾
IO 宿æ¶è½å¤å»å®æå
¶å®äºæ
ï¼å½ IO 宿æ¶çº¿ç¨å¯ä»¥åæ¥ç»§ç»å¤ç IO ç¸å
³æä½ï¼ä¸å¿
干干çåç IO 宿ã**å¨ IO å¤ççè¿ç¨ä¸ï¼è½å¤æä¸ä¸ª**ä¸é¨ç线ç¨è´è´£çå¬è¿äº IO æä½ï¼éç¥æå¡å¨è¯¥å¦ä½æä½**ãæä»¥ï¼æä»¬èå° IOï¼ä¸å¾ä¸å»æ¥è§¦ NIO è¿ä¸å硬骨头ã
## æ°æ½®ç NIO
æä»¬æ¥çç BIO å NIO çåºå«ï¼BIO æ¯**é¢åæµ**ç IOï¼å®å»ºç«çéé齿¯**åå**çï¼æä»¥è¾å
¥åè¾åºæµçééä¸ç¸åï¼å¿
须建ç«2个ééï¼ééå
ç齿¯ä¼ è¾==0101001···==çåèæ°æ®ã

èå¨ NIO ä¸ï¼ä¸åæ¯é¢åæµç IO äºï¼èæ¯é¢å**ç¼å²åº**ï¼å®ä¼å»ºç«ä¸ä¸ª**ééï¼Channelï¼**ï¼è¯¥ééæä»¬å¯ä»¥ç解为**éè·¯**ï¼è¯¥éè·¯ä¸å¯ä»¥è¿è¾åç§è´§ç©ï¼èééä¸ä¼æä¸ä¸ª**ç¼å²åºï¼Bufferï¼**ç¨äºåå¨çæ£çæ°æ®ï¼ç¼å²åºæä»¬å¯ä»¥ç解为**ä¸è¾ç«è½¦**ã
**ééï¼éè·¯ï¼**åªæ¯ä½ä¸ºè¿è¾æ°æ®çä¸ä¸ªè¿æ¥èµæºï¼èçæ£å卿°æ®çæ¯**ç¼å²åºï¼ç«è½¦ï¼**ãå³**ééè´è´£ä¼ è¾ï¼ç¼å²åºè´è´£åå¨ã**

çè§£äºä¸é¢çå¾ä¹åï¼BIO å NIO ç主è¦åºå«å°±å¯ä»¥ç¨ä¸é¢è¿ä¸ªè¡¨æ ¼ç®åæ¦æ¬ã
| BIO | NIO |
| :--------------: | :------------------: |
| é¢åæµï¼Streamï¼ | é¢åç¼å²åºï¼Bufferï¼ |
| ååéé | ååéé |
| é»å¡ IO | éé»å¡ IO |
| | éæ©å¨ï¼Selectorsï¼ |
## ç¼å²åºï¼Bufferï¼
ç¼å²åºæ¯**å卿°æ®**çåºåï¼å¨ Java ä¸ï¼ç¼å²åºå°±æ¯æ°ç»ï¼ä¸ºäºå¯ä»¥æä½ä¸åæ°æ®ç±»åçæ°æ®ï¼Java æä¾äºè®¸å¤ä¸åç±»åçç¼å²åºï¼**é¤äºå¸å°ç±»å以å¤**ï¼å
¶å®åºæ¬æ°æ®ç±»å齿坹åºçç¼å²åºæ°ç»å¯¹è±¡ã

> 为ä»ä¹æ²¡æå¸å°ç±»åçç¼å²åºå¢ï¼
>
> å¨ Java ä¸ï¼boolean ç±»åæ°æ®åªå ç¨ `1 bit`ï¼èå¨ IO ä¼ è¾è¿ç¨ä¸ï¼é½æ¯ä»¥åè为åä½è¿è¡ä¼ è¾çï¼æä»¥ boolean ç 1 bit å®å
¨å¯ä»¥ä½¿ç¨ byte ç±»åçæä¸ä½ï¼æè
int ç±»åçæä¸ä½æ¥è¡¨ç¤ºï¼æ²¡æå¿
è¦ä¸ºäºè¿ 1 bit èä¸é¨æä¾å¤ä¸ä¸ªç¼å²åºã
| ç¼å²åº | è§£é |
| :----------: | :------------------------------: |
| ByteBuffer | åå¨**åèæ°æ®**çç¼å²åº |
| CharBuffer | åå¨**åç¬¦æ°æ®**çç¼å²åº |
| ShortBuffer | åå¨**çæ´åæ°æ®**çç¼å²åº |
| IntBuffer | åå¨**æ´åæ°æ®**çç¼å²åº |
| LongBuffer | åå¨**é¿æ´åæ°æ®**çç¼å²åº |
| FloatBuffer | åå¨**å精度浮ç¹åæ°æ®**çç¼å²åº |
| DoubleBuffer | åå¨**å精度浮ç¹åæ°æ®**çç¼å²åº |
åé
ä¸ä¸ªç¼å²åºçæ¹å¼é½é«åº¦ä¸è´ï¼ä½¿ç¨`allocate(int capacity)`æ¹æ³ã
ä¾å¦éè¦åé
ä¸ä¸ª 1024 大å°çåèæ°ç»ï¼ä»£ç å°±æ¯ä¸é¢è¿æ ·åã
```java
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
```
ç¼å²åº**è¯»åæ°æ®**çä¸¤ä¸ªæ ¸å¿æ¹æ³ï¼
- put()ï¼å°æ°æ®åå
¥å°ç¼å²åºä¸
- get()ï¼ä»ç¼å²åºä¸è¯»åæ°æ®
ç¼å²åºçéè¦å±æ§ï¼
- **capacity**ï¼ç¼å²åºä¸**æå¤§å卿°æ®ç容é**ï¼ä¸æ¦å£°æåæ æ³æ¹å
- **limit**ï¼è¡¨ç¤ºç¼å²åºä¸**å¯ä»¥æä½æ°æ®ç大å°**ï¼limit ä¹åçæ°æ®æ æ³è¿è¡è¯»åãå¿
须满足 limit <= capacity
- **position**ï¼å½åç¼å²åºä¸**æ£å¨æä½æ°æ®ç䏿 ä½ç½®**ï¼å¿
须满足 position <= limit
- **mark**ï¼æ è®°ä½ç½®ï¼è°ç¨ reset() å° position ä½ç½®è°æ´å° mark 屿§æåç䏿 ä½ç½®ï¼**å®ç°å¤æ¬¡è¯»åæ°æ®**
ç¼å²åºä¸ºé«æè¯»åæ°æ®èæä¾çå
¶å®**è¾
婿¹æ³**ï¼
- flip()ï¼å¯ä»¥å®ç°**è¯»åæ¨¡å¼ç忢**ï¼æä»¬å¯ä»¥ççéé¢çæºç
```java
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
```
è°ç¨ flip() ä¼å°å¯æä½çå¤§å° limit 设置为å½ååçä½ç½®ï¼æä½æ°æ®çèµ·å§ä½ç½® position 设置为 0ï¼å³**ä»å¤´å¼å§è¯»åæ°æ®**ã
- rewind()ï¼å¯ä»¥å° position ä½ç½®è®¾ç½®ä¸º 0ï¼å次读åç¼å²åºä¸çæ°æ®
- clear()ï¼æ¸
空æ´ä¸ªç¼å²åºï¼å®ä¼å° position 设置为 0ï¼limit 设置为 capacityï¼å¯ä»¥**åæ´ä¸ªç¼å²åº**
> æ´å¤çæ¹æ³å¯ä»¥å»æ¥é
API ææ¡£ï¼æ¬æç¢äºç¯å¹
åå å°±ä¸è´´åºå
¶å®æ¹æ³äºï¼ä¸»è¦æ¯è¦**çè§£ç¼å²åºçä½ç¨**
æä»¬æ¥çä¸ä¸ªç®åçä¾å
```java
public Class Main {
public static void main(String[] args) {
// åé
å
å大å°ä¸º11çæ´åç¼ååº
IntBuffer buffer = IntBuffer.allocate(11);
// å¾bufferéåå
¥2个æ´åæ°æ®
for (int i = 0; i < 2; ++i) {
int randomNum = new SecureRandom().nextInt();
buffer.put(randomNum);
}
// å°Bufferä»å模å¼åæ¢å°è¯»æ¨¡å¼
buffer.flip();
System.out.println("position >> " + buffer.position()
+ "limit >> " + buffer.limit()
+ "capacity >> " + buffer.capacity());
// 读åbufferéçæ°æ®
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
System.out.println("position >> " + buffer.position()
+ "limit >> " + buffer.limit()
+ "capacity >> " + buffer.capacity());
}
}
```
æ§è¡ç»æå¦ä¸å¾æç¤ºï¼é¦å
æä»¬å¾ç¼å²åºä¸åå
¥ 2 ä¸ªæ°æ®ï¼position å¨å模å¼ä¸æå䏿 2ï¼ç¶åè°ç¨ flip() æ¹æ³åæ¢ä¸ºè¯»æ¨¡å¼ï¼limit æå䏿 2ï¼position ä» 0 å¼å§è¯»æ°æ®ï¼è¯»å°ä¸æ 为 2 æ¶åç°å°è¾¾ limit ä½ç½®ï¼ä¸å¯ç»§ç»è¯»ã

æ´ä¸ªè¿ç¨å¯ä»¥ç¨ä¸å¾æ¥çè§£ï¼è°ç¨ flip() æ¹æ³ä»¥åï¼è¯»åºæ°æ®çåæ¶ position æé䏿å¾åæªå¨ï¼å°è¾¾ limit æéçä½ç½®æ¶ï¼è¯¥æ¬¡è¯»åæä½ç»æã

> ä»ç»å®ç¼å²åºåï¼æä»¬ç¥é宿¯å卿°æ®ç空é´ï¼è¿ç¨å¯ä»¥å°ç¼å²åºä¸çæ°æ®è¯»ååºæ¥ï¼ä¹å¯ä»¥åå
¥æ°çæ°æ®å°ç¼å²åºï¼é£ç¼å²åºçæ°æ®ä»åªéæ¥ï¼åæä¹ååºå»å¢ï¼æ¥ä¸æ¥æä»¬éè¦å¦ä¹ ä¼ è¾æ°æ®çä»è´¨ï¼ééï¼Channelï¼
## ééï¼Channelï¼
ä¸é¢æä»¬ä»ç»è¿ï¼é鿝ä½ä¸ºä¸ç§è¿æ¥èµæºï¼ä½ç¨æ¯ä¼ è¾æ°æ®ï¼èçæ£å卿°æ®çæ¯ç¼å²åºï¼æä»¥ä»ç»å®ç¼å²åºåï¼æä»¬æ¥å¦ä¹ ééè¿ä¸åã
é鿝å¯ä»¥**åå读å**çï¼ä¼ ç»ç BIO éè¦ä½¿ç¨è¾å
¥/è¾åºæµè¡¨ç¤ºæ°æ®çæµåï¼å¨ NIO ä¸å¯ä»¥åå°ééèµæºçæ¶èã

ééç±»é½ä¿åå¨ `java.nio.channels` å
ä¸ï¼æä»¬æ¥å¸¸ç¨å°çå 个éè¦çç±»æ 4 个ï¼
| IO ééç±»å | å
·ä½ç±» |
| :---------: | :----------------------------------------------------------: |
| æä»¶ IO | FileChannelï¼ç¨äºæä»¶è¯»åãæä½æä»¶çééï¼ |
| TCP ç½ç» IO | SocketChannelï¼ç¨äºè¯»åæ°æ®ç TCP ééï¼ãServerSocketChannelï¼çå¬å®¢æ·ç«¯çè¿æ¥ï¼ |
| UDP ç½ç» IO | DatagramChannelï¼æ¶å UDP æ°æ®æ¥çééï¼ |
å¯ä»¥éè¿ `getChannel()` æ¹æ³è·åä¸ä¸ªééï¼æ¯æè·åééçç±»å¦ä¸ï¼
- æä»¶ IOï¼FileInputStreamãFileOutputStreamãRandomAccessFile
- TCP ç½ç» IOï¼SocketãServerSocket
- UDP ç½ç» IOï¼DatagramSocket
### 示ä¾ï¼æä»¶æ·è´æ¡ä¾
æä»¬æ¥çä¸ä¸ªå©ç¨**ééæ·è´æä»¶**çä¾åï¼éè¦ä¸é¢å 个æ¥éª¤ï¼
- æå¼åæä»¶çè¾å
¥æµééï¼å°åèæ°æ®è¯»å
¥å°ç¼å²åºä¸
- æå¼ç®çæä»¶çè¾åºæµééï¼å°ç¼å²åºä¸çæ°æ®åå°ç®çå°
- å
³éæææµåééï¼éè¦ï¼ï¼
è¿æ¯ä¸å¼ å°è èçç
§çï¼å®åå¨äº`d:\å°è è\`æä»¶å¤¹ä¸ï¼æä»¬å°å®æ·è´å° `d:\å°è èå身\` æä»¶å¤¹ä¸ã

```java
public class Test {
/** ç¼å²åºçå¤§å° */
public static final int SIZE = 1024;
public static void main(String[] args) throws IOException {
// æå¼æä»¶è¾å
¥æµ
FileChannel inChannel = new FileInputStream("d:\å°è è\å°è è.jpg").getChannel();
// æå¼æä»¶è¾åºæµ
FileChannel outChannel = new FileOutputStream("d:\å°è èå身\å°è è-æ·è´.jpg").getChannel();
// åé
1024 个åè大å°çç¼å²åº
ByteBuffer dsts = ByteBuffer.allocate(SIZE);
// å°æ°æ®ä»éé读å
¥ç¼å²åº
while (inChannel.read(dsts) != -1) {
// 忢ç¼å²åºçè¯»åæ¨¡å¼
dsts.flip();
// å°ç¼å²åºçæ°æ®éè¿ééåå°ç®çå°
outChannel.write(dsts);
// æ¸
空ç¼å²åºï¼åå¤ä¸ä¸æ¬¡è¯»
dsts.clear();
}
inChannel.close();
outChannel.close();
}
}
```
æç»äºä¸å¼ å¾å¸®å©ä½ çè§£ä¸é¢çè¿ä¸ä¸ªè¿ç¨ã

> æäººä¼é®ï¼NIO çæä»¶æ·è´åä¼ ç» IO æµçæä»¶æ·è´æä½ä¸åå¢ï¼æä»¬å¨ç¼ç¨æ¶æè§å®ä»¬æ²¡æä»ä¹åºå«åï¼**è²ä¼¼åªæ¯ API ä¸åç½¢äº**ï¼æä»¬æ¥ä¸æ¥å°±å»ççè¿ä¸¤è
ä¹é´çåºå«å§ã
### BIO å NIO æ·è´æä»¶çåºå«
è¿ä¸ªæ¶åå°±è¦æ¥äºè§£äºè§£æä½ç³»ç»åºå±æ¯æä¹å¯¹ IO å NIO è¿è¡åºå«çï¼æä¼ç¨å°½ééä¿çæåå¸¦ä½ çè§£ï¼å¯è½å¹¶ä¸æ¯é£ä¹ä¸¥è°¨ã
æä½ç³»ç»æéè¦çå°±æ¯**å
æ ¸**ï¼å®æ¢å¯ä»¥è®¿é®åä¿æ¤çå
åï¼ä¹å¯ä»¥è®¿é®åºå±ç¡¬ä»¶è®¾å¤ï¼æä»¥ä¸ºäºä¿æ¤å
æ ¸çå®å
¨ï¼æä½ç³»ç»å°åºå±çèæç©ºé´å为äº**ç¨æ·ç©ºé´**å**å
æ ¸ç©ºé´**ï¼å
¶ä¸ç¨æ·ç©ºé´å°±æ¯ç»ç¨æ·è¿ç¨ä½¿ç¨çï¼å
æ ¸ç©ºé´å°±æ¯ä¸é¨ç»æä½ç³»ç»åºå±å»ä½¿ç¨çã

æ¥ä¸æ¥ï¼æä¸ä¸ª Java è¿ç¨å¸ææå°è èè¿å¼ å¾çä»ç£ç䏿·è´ï¼é£ä¹å
æ ¸ç©ºé´åç¨æ·ç©ºé´é½ä¼æä¸ä¸ª**ç¼å²åº**
- è¿å¼ ç
§çå°±ä¼ä»ç£çä¸è¯»åºå°**å
æ ¸ç¼å²åº**ä¸ä¿åï¼ç¶åæä½ç³»ç»å°å
æ ¸ç¼å²åºä¸çè¿å¼ å¾çåèæ°æ®æ·è´å°ç¨æ·è¿ç¨çç¼å²åºä¸ä¿å䏿¥ï¼å¯¹åºçä¸é¢è¿å¹
å¾

- ç¶åç¨æ·è¿ç¨ä¼å¸ææç¼å²åºä¸çåèæ°æ®åå°ç£çä¸çå¦å¤ä¸ä¸ªå°æ¹ï¼ä¼å°æ°æ®æ·è´å° Socket ç¼å²åºä¸ï¼æç»æä½ç³»ç»åå° Socket ç¼å²åºçæ°æ®åå°ç£ççæå®ä½ç½®ä¸ã

è¿ä¸è½®æä½ä¸æ¥ï¼æä»¬æ°æ°ç»è¿äºå æ¬¡æ°æ®çæ·è´ï¼`4` æ¬¡ãæ 2 次æ¯**å
æ ¸ç©ºé´åç¨æ·ç©ºé´ä¹é´çæ°æ®æ·è´**ï¼è¿ä¸¤æ¬¡æ·è´æ¶åå°**ç¨æ·æåå
æ ¸æç忢**ï¼éè¦**CPUåä¸è¿æ¥**ï¼è¿è¡ä¸ä¸æåæ¢ãèå¦å¤ 2 次æ¯**硬çåå
æ ¸ç©ºé´ä¹é´çæ°æ®æ·è´**ï¼è¿ä¸ªè¿ç¨å©ç¨å° DMAä¸ç³»ç»å
åäº¤æ¢æ°æ®ï¼ä¸éè¦ CPU çåä¸ã
å¯¼è´ IO æ§è½ç¶é¢çåå ï¼**å
æ ¸ç©ºé´ä¸ç¨æ·ç©ºé´ä¹é´æ°æ®è¿å¤æ æä¹çæ·è´ï¼ä»¥å夿¬¡ä¸ä¸æåæ¢**
| æä½ | ç¶æ |
| ------------------------------ | :--------------- |
| ç¨æ·è¿ç¨è¯·æ±è¯»åæ°æ® | ç¨æ·æ -> å
æ ¸æ |
| æä½ç³»ç»å
æ ¸è¿åæ°æ®ç»ç¨æ·è¿ç¨ | å
æ ¸æ -> ç¨æ·æ |
| ç¨æ·è¿ç¨è¯·æ±åæ°æ®å°ç¡¬ç | ç¨æ·æ -> å
æ ¸æ |
| æä½ç³»ç»è¿åæä½ç»æç»ç¨æ·è¿ç¨ | å
æ ¸æ -> ç¨æ·æ |
> å¨ç¨æ·ç©ºé´ä¸å
æ ¸ç©ºé´ä¹é´çæä½ï¼ä¼æ¶åå°ä¸ä¸æç忢ï¼è¿ééè¦ CPU çå¹²é¢ï¼èæ°æ®å¨ä¸¤ä¸ªç©ºé´ä¹é´æ¥åæ·è´ï¼ä¹éè¦ CPU çå¹²é¢ï¼è¿æ çä¼å¢å¤§ CPU çååï¼NIO æ¯å¦ä½åè½» CPU çååï¼è¿ç¨æä½ç³»ç»ç**é¶æ·è´**ææ¯ã
### æä½ç³»ç»çé¶æ·è´
æä»¥ï¼æä½ç³»ç»åºç°äºä¸ä¸ªå
¨æ°çæ¦å¿µï¼è§£å³äº IO ç¶é¢ï¼**é¶æ·è´**ãé¶æ·è´æçæ¯**å
æ ¸ç©ºé´ä¸ç¨æ·ç©ºé´ä¹é´çé¶æ¬¡æ·è´**ã
é¶æ·è´å¯ä»¥è¯´æ¯ IO çä¸å¤§ææï¼æä½ç³»ç»åºå±æè®¸å¤ç§é¶æ·è´æºå¶ï¼æè¿éä»
é对 Java NIO ä¸ä½¿ç¨å°çå
¶ä¸ä¸ç§é¶æ·è´æºå¶å±å¼è®²è§£ã
å¨ Java NIO ä¸ï¼é¶æ·è´æ¯éè¿**ç¨æ·ç©ºé´åå
æ ¸ç©ºé´çç¼å²åºå
±äº«ä¸åç©çå
å**å®ç°çï¼ä¹å°±æ¯è¯´ä¸é¢çå¾å¯ä»¥æ¼åæè¿ä¸ªæ ·åã

è¿æ¶ï¼æ 论æ¯ç¨æ·ç©ºé´è¿æ¯å
æ ¸ç©ºé´æä½èªå·±çç¼å²åºï¼æ¬è´¨ä¸é½æ¯**æä½è¿ä¸åå
±äº«å
å**ä¸çç¼å²åºæ°æ®ï¼**çå»äºç¨æ·ç©ºé´åå
æ ¸ç©ºé´ä¹é´çæ°æ®æ·è´æä½**ã
ç°å¨æä»¬éæ°æ¥æ·è´æä»¶ï¼å°±ä¼åæä¸é¢è¿ä¸ªæ¥éª¤ï¼
- ç¨æ·è¿ç¨éè¿ç³»ç»è°ç¨ `read()` 请æ±è¯»åæä»¶å°ç¨æ·ç©ºé´ç¼å²åºï¼**ç¬¬ä¸æ¬¡ä¸ä¸æåæ¢**ï¼ï¼ç¨æ·æ -> æ ¸å¿æï¼æ°æ®ä»ç¡¬ç读åå°å
æ ¸ç©ºé´ç¼å²åºä¸ï¼**ç¬¬ä¸æ¬¡æ°æ®æ·è´**ï¼
- ç³»ç»è°ç¨è¿åå°ç¨æ·è¿ç¨ï¼**ç¬¬äºæ¬¡ä¸ä¸æåæ¢**ï¼ï¼æ¤æ¶ç¨æ·ç©ºé´ä¸å
æ ¸ç©ºé´å
±äº«è¿ä¸åå
åï¼ç¼å²åºï¼ï¼æä»¥**ä¸éè¦ä»å
æ ¸ç¼å²åºæ·è´å°ç¨æ·ç¼å²åº**
- ç¨æ·è¿ç¨ååº `write()` ç³»ç»è°ç¨è¯·æ±åæ°æ®å°ç¡¬çä¸ï¼**ç¬¬ä¸æ¬¡ä¸ä¸æåæ¢**ï¼ï¼æ¤æ¶éè¦å°å
æ ¸ç©ºé´ç¼å²åºä¸çæ°æ®æ·è´å°å
æ ¸ç Socket ç¼å²åºä¸ï¼**ç¬¬äºæ¬¡æ°æ®æ·è´**ï¼
- ç± DMA å° Socket ç¼å²åºçå
容åå°ç¡¬çä¸ï¼**ç¬¬ä¸æ¬¡æ°æ®æ·è´**ï¼ï¼`write()` ç³»ç»è°ç¨è¿åï¼**ç¬¬åæ¬¡ä¸ä¸æåæ¢**ï¼
æ´ä¸ªè¿ç¨å°±å¦ä¸é¢è¿å¹
å¾æç¤ºã

å¾ä¸ï¼**éè¦ CPU åä¸å·¥ä½çæ¥éª¤åªæç¬¬â¢ä¸ªæ¥éª¤**ï¼å¯¹æ¯äºä¼ ç»ç IOï¼CPU éè¦å¨ç¨æ·ç©ºé´ä¸å
æ ¸ç©ºé´ä¹é´å䏿·è´å·¥ä½ï¼éè¦æ æä¹å°å ç¨ 2 次 CPU èµæºï¼å¯¼è´ CPU èµæºç浪费ã
ä¸é¢æ»ç»ä¸ä¸æä½ç³»ç»ä¸é¶æ·è´çä¼ç¹ï¼
- **éä½ CPU çåå**ï¼é¿å
CPU éè¦åä¸å
æ ¸ç©ºé´ä¸ç¨æ·ç©ºé´ä¹é´çæ°æ®æ·è´å·¥ä½
- **åå°ä¸å¿
è¦çæ·è´**ï¼é¿å
ç¨æ·ç©ºé´ä¸å
æ ¸ç©ºé´ä¹é´éè¦è¿è¡æ°æ®æ·è´
ä¸é¢çå¾ç¤ºå¯è½å¹¶ä¸ä¸¥è°¨ï¼å¯¹äºä½ çè§£é¶æ·è´ä¼æä¸å®ç帮å©ï¼å
³äºé¶æ·è´çç¥è¯ç¹å¯ä»¥å»æ¥é
æ´å¤èµæå¦ï¼è¿æ¯ä¸é¨å¤§å¦é®ã
> ä»ç»å®ééåï¼æä»¬ç¥é宿¯ç¨äº**ä¼ è¾æ°æ®çä¸ç§ä»è´¨**ï¼è䏿¯**å¯ä»¥åå读å**çï¼é£ä¹å¦ææ¾å¨ç½ç» IO ä¸ï¼è¿äºééå¦æææ°æ®å°±ç»ªæ¶ï¼æå¡å¨æ¯å¦ä½åç°å¹¶å¤ççå¢ï¼æ¥ä¸æ¥æä»¬å»å¦ä¹ NIO ä¸çæåä¸ä¸ªéè¦ç¥è¯ç¹ï¼éæ©å¨ï¼Selectorï¼
## éæ©å¨ï¼Selectorsï¼
鿩卿¯æå IO æ§è½ççµéä¹ä¸ï¼å®åºå±å©ç¨äº**å¤è·¯å¤ç¨ IO**æºå¶ï¼è®©éæ©å¨å¯ä»¥çå¬å¤ä¸ª IO è¿æ¥ï¼æ ¹æ® IO çç¶æååºå°æå¡å¨ç«¯è¿è¡å¤çãéä¿å°è¯´ï¼**éæ©å¨å¯ä»¥çå¬å¤ä¸ª IO è¿æ¥ï¼èä¼ ç»ç BIO æ¯ä¸ª IO è¿æ¥é½éè¦æä¸ä¸ªçº¿ç¨å»çå¬åå¤çã**

å¾ä¸å¾ææ¾çæ¾ç¤ºäºå¨ BIO ä¸ï¼æ¯ä¸ª Socket é½éè¦æä¸ä¸ªä¸é¨ç线ç¨å»å¤çæ¯ä¸ªè¯·æ±ï¼èå¨ NIO ä¸ï¼åªéè¦ä¸ä¸ª Selector å³å¯çå¬å个 Socket 请æ±ï¼èä¸ Selector 并䏿¯é»å¡çï¼æä»¥**ä¸ä¼å 为å¤ä¸ªçº¿ç¨ä¹é´åæ¢å¯¼è´ä¸ä¸æåæ¢å¸¦æ¥çå¼é**ã

å¨ Java NIO ä¸ï¼éæ©å¨æ¯ä½¿ç¨ `Selector` 类表示ï¼Selector å¯ä»¥æ¥æ¶åç§ IO è¿æ¥ï¼å¨ IO ç¶æåå¤å°±ç»ªæ¶ï¼ä¼éç¥è¯¥ééæ³¨åç Selectorï¼Selector å¨**ä¸ä¸æ¬¡è½®è¯¢**æ¶ä¼åç°è¯¥ IO è¿æ¥å°±ç»ªï¼è¿èå¤çè¯¥è¿æ¥ã
Selector éæ©å¨ä¸»è¦ç¨äº**ç½ç» IO**å½ä¸ï¼å¨è¿éæä¼å°ä¼ ç»ç BIO Socket ç¼ç¨åä½¿ç¨ NIO åç Socket ç¼ç¨ä½å¯¹æ¯ï¼åæ NIO ä¸ºä½æ´å欢è¿ãé¦å
å
æ¥äºè§£ Selector çåºæ¬ç»æã
| éè¦æ¹æ³ | æ¹æ³è§£æ |
| :----------------------: | :----------------------------------------------------------: |
| open() | æå¼ä¸ä¸ª Selector éæ©å¨ |
| int select() | é»å¡å°çå¾
就绪çéé |
| int select(long timeout) | æå¤é»å¡ timeout 毫ç§ï¼å¦ææ¯ 0 åä¸ç´é»å¡çå¾
ï¼å¦ææ¯ 1 å代表æå¤é»å¡ 1 æ¯«ç§ |
| int selectNow() | éé»å¡å°è½®è¯¢å°±ç»ªçéé |
å¨è¿éï¼ä½ ä¼çå° select() åå®çéè½½æ¹æ³æ¯ä¼é»å¡çï¼å¦æç¨æ·è¿ç¨è½®è¯¢æ¶åç°æ²¡æå°±ç»ªçééï¼æä½ç³»ç»æä¸¤ç§åæ³ï¼
- ä¸ç´çå¾
ç´å°ä¸ä¸ªå°±ç»ªçééï¼åè¿åç»ç¨æ·è¿ç¨
- ç«å³è¿åä¸ä¸ªéè¯¯ç¶æç ç»ç¨æ·è¿ç¨ï¼è®©ç¨æ·è¿ç¨ç»§ç»è¿è¡ï¼ä¸ä¼é»å¡
è¿ä¸¤ç§æ¹æ³å¯¹åºäº**忥é»å¡ IO** å **忥éé»å¡ IO** ï¼è¿é读è
çä¸ç¹å°çè§ç¹ï¼è¯·åä½å¤§ç¥**æ¹å¤é
读**
> Java ä¸ç NIO ä¸è½çæ£æä¹ä¸ç§°ä¸º Non-Blocking IOï¼æä»¬éè¿ API çè°ç¨å¯ä»¥åç°ï¼select() æ¹æ³è¿æ¯ä¼åå¨é»å¡çç°è±¡ï¼æ ¹æ®ä¼ å
¥çåæ°ä¸åï¼æä½ç³»ç»çè¡ä¸ºä¹ä¼ææä¸åï¼ä¸åä¹å¤å°±æ¯**é»å¡è¿æ¯éé»å¡**ï¼æä»¥ææ´å¾åäºæ NIO 称为 New IOï¼å 为å®ä¸ä»
æä¾äº Non-Blocking IOï¼èä¸ä¿çåæç Blocking IO çåè½ã
äºè§£äºéæ©å¨ä¹åï¼å®çä½ç¨å°±æ¯ï¼**çå¬å¤ä¸ª IO ééï¼å½æéé就绪æ¶éæ©å¨ä¼è½®è¯¢åç°è¯¥ééï¼å¹¶åç¸åºçå¤ç**ãé£ä¹ IO ç¶æå为å¾å¤ç§ï¼æä»¬å¦ä½å»è¯å«å°±ç»ªçé鿝å¤äºåªç§ç¶æå¢ï¼å¨ Java 䏿ä¾äº**éæ©é®ï¼SelectionKeyï¼**ã
### éæ©é®ï¼SelectionKeyï¼
å¨ Java 䏿ä¾äº 4 ç§éæ©é®ï¼
- SelectionKey.OP_READï¼å¥æ¥åééåå¤å¥½è¿è¡**读æä½**
- SelectionKey.OP_WRITEï¼å¥æ¥åééåå¤å¥½è¿è¡**åæä½**
- SelectionKey.OP_ACCEPTï¼æå¡å¨å¥æ¥åéé**æ¥åå
¶å®éé**
- SelectionKey.OP_CONNECTï¼å¥æ¥åééåå¤**å®æè¿æ¥**
å¨ SelectionKey ä¸å
å«äºè®¸å¤å±æ§
- channelï¼è¯¥éæ©é®**ç»å®çéé**
- selectorï¼è½®è¯¢å°è¯¥éæ©é®ç**éæ©å¨**
- readyOpsï¼å½å**å°±ç»ªéæ©é®çå¼**
- interesOpsï¼è¯¥éæ©å¨å¯¹è¯¥éé**æå
´è¶£çææéæ©é®**
éæ©é®çä½ç¨æ¯ï¼**å¨éæ©å¨è½®è¯¢å°æå°±ç»ªééæ¶ï¼ä¼è¿åè¿äºééçå°±ç»ªéæ©é®ï¼SelectionKeyï¼ï¼éè¿éæ©é®å¯ä»¥è·åå°ééè¿è¡æä½ã**
ç®åäºè§£äºéæ©å¨åï¼æä»¬å¯ä»¥ç»åç¼å²åºãééå鿩卿¥å®æä¸ä¸ªç®æçè天室åºç¨ã
### 示ä¾ï¼ç®æç客æ·ç«¯æå¡å¨éä¿¡
> å
说æï¼è¿éç代ç é常çèåé¿ï¼ä¸æ¨èç»çï¼ç´æ¥ç注ééè¿ç代ç å³å¯ã
æä»¬å¨æå¡å¨ç«¯ä¼å¼è¾ä¸¤ä¸ªçº¿ç¨
- Thread1ï¼ä¸é¨çå¬å®¢æ·ç«¯çè¿æ¥ï¼å¹¶æééæ³¨åå°å®¢æ·ç«¯éæ©å¨ä¸
- Thread2ï¼ä¸é¨çå¬å®¢æ·ç«¯çå
¶å® IO ç¶æï¼è¯»ç¶æï¼ï¼å½å®¢æ·ç«¯ç IO ç¶æå°±ç»ªæ¶ï¼è¯¥éæ©å¨ä¼è½®è¯¢åç°ï¼å¹¶ä½ç¸åºå¤ç
```java
public class NIOServer {
Selector serverSelector = Selector.open();
Selector clientSelector = Selector.open();
public static void main(String[] args) throws IOException {
NIOServer server = nwe NIOServer();
new Thread(() -> {
try {
// 对åºIOç¼ç¨ä¸æå¡ç«¯å¯å¨
ServerSocketChannel listenerChannel = ServerSocketChannel.open();
listenerChannel.socket().bind(new InetSocketAddress(3333));
listenerChannel.configureBlocking(false);
listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT);
server.acceptListener();
} catch (IOException ignored) {
}
}).start();
new Thread(() -> {
try {
server.clientListener();
} catch (IOException ignored) {
}
}).start();
}
}
// çå¬å®¢æ·ç«¯è¿æ¥
public void acceptListener() {
while (true) {
if (serverSelector.select(1) > 0) {
Set