è¯è åºï¼è¿æ¯ä¸ç¯æ¯è¾ä½¿ç¨çI/Oæ°ç¹æ§çä»ç»æç« ãæä¸ä½¿ç¨äºå¤§éç代ç å®ä¾æ¥æ¼ç¤ºå解说å¦ä½ä½¿ç¨J2SE1.4çæ°I/Oç¹æ§å¹¶æä¾ä½ åºç¨ç¨åºçæ§è½ï¼èä¸æä¾äºä¸¤ä¸ªå®æ´çä¾åï¼å ¶ä¸å æ¬ä¸ä¸ªå¾ªç¯WEBæå¡å¨çéå½¢ï¼é常å¼å¾æ们åèã
ããå溯å°2000å¹´ç1æï¼å½äººä»¬æ£å¨äºè®ºçå ¬å 2000年究ç«æ¯ä¸ä¸ªä¸çºªçå¼å§è¿æ¯ä¸ä¸ªå®é çç»æçæ¶åï¼ä¸ä»½æ°çJAVAè§èââJSRï¼Java Specification Requestï¼51ä¹è¢«å®¡æ ¸éè¿äºãè¿ä»½JSRçååæ¯ãNew I/O APIs for the Java Platformãï¼JAVAå¹³å°çæ°I/O APIï¼ã许å¤äººè®¤ä¸ºè¿ä»½æ°çè§èåªä¼ç»å¤§å®¶å¸¦æ¥éé»å¡I/Oæä½çè½åï¼ä½æ¯å¨JSDK1.4Betaï¼JavaTM 2 Platform, Standard Editionï¼ä¸å¼å ¥çæ°çç¹æ§ï¼å´è¿å å«å ¶å®çä¸äºæ°èæ趣çç¹å¾ãæ°çAPIå¨æä¾äºå¯å级çå¥æ¥å£ï¼socketï¼åæ件I/Oæä½çåæ¶ï¼è¿æ¯çæå½ç¶çï¼ï¼ä½ ä¹å¯ä»¥æ¾å°ä¸ä¸ªæ£å表达çå æ¥æ¯æ模å¼å¹é ï¼ä»¥å对å符é转æ¢çç¼ç å¨å解ç å¨ï¼åä¼åè¿çæ件系ç»æ¯æå¦æ件éå®ãå åæ å°çåè½ãæ们å¨è¿ç¯æç« ä¸ç讨论ä¼å ¨é¢è¦çä¸é¢æ说çå个æ°ç¹æ§ã注æï¼JAVAæ¬å°æ¥å£ï¼JNIï¼ä¸ºæ°çI/Oæä½æåçä¿®æ¹æ们å°ä¸ä¼æ¶åï¼å¦æä½ éè¦äºè§£æå ³çå 容ï¼è¯·åèæ¬æç»å°¾âèµæºâé¨åçæå ³å 容ã
ãBuffers
ãã
ããæç §ä»æç®åå°æå¤æçä¹ æ¯ï¼æ们å°ä»java.nioå ä¸çä¸ç³»åBufferç±»å¼å§è¯´èµ·ãBufferæä¾äºä¸ç§å¨å å容å¨ä¸ä¿åä¸ç³»ååå§æ°æ®çæºå¶ãåºæ¬ä¸ï¼ä½ å¯ä»¥è®¾æ³ä¸ä¸ï¼æDataInputStream/DataOutputStreamç»åå¨ä¸èµ·å°è£ æä¸ä¸ªåºå®åè大å°çæ°ç»èåªå 许读åä¸ç§æ°æ®ç±»åï¼ä¾å¦charï¼intï¼æè doubleãå¨è¿ä¸ªå éï¼æ»å ±æ7ç§è¿æ ·çBufferå¯ç¨ï¼
ãã
ãã· ByteBuffer · CharBuffer · DoubleBuffer · FloatBuffer · IntBuffer · LongBuffer · ShortBuffer
ã
ããå®é ä¸ï¼ByteBufferä¹è½å¤å¯¹å ¶å®å ç§ç±»åè¿è¡è¯»åï¼ä½æ¯è¿äºç¹å«çBufferæ´æé对æ§ï¼æ´ä¸é¨åä¸äºã为äºç¤ºèå¦ä½ä½¿ç¨ä¸ä¸ªBufferï¼æ¥ä¸æ¥è¿ä¸å°ç代ç å°å®æä¸ä¸ªä»Stringååéå°ä¸ä¸ªCharBufferç转æ¢ï¼å¹¶ä»è¿ä¸ªBufferä¸éä¸ç读åºå个å符ãä½ å¯ä»¥ç¨warpæ¹æ³æ¥å®æ转æ¢ï¼ç¨getæ¹æ³æ¥åä¸ä¸ªå符ã
ã
ããCharBuffer buff = CharBuffer.wrap(args[0]);
ãã
ããfor (int i=0, n=buff.length(); iãã
ãã{System.out.println(buff.get());}
ãã
ããå¨ä½¿ç¨Bufferçæ¶åï¼ä¸å®è¦æ³¨æå®ç®åç大å°ï¼sizingï¼åä½ç½®ï¼positioningï¼çå¼æ¯æåºå«çï¼åä¸ä¸è¦æ··æ·äºãæ¹æ³lengthæ¯ä¸è§èçï¼å°¤å ¶æ¯å¯¹äºCharBufferèè¨ãå½ç¶è¿å¹¶éæ¯åºäºä»ä¹éï¼èæ¯å®è¿åçæ¯Bufferä¸çå©ä½é¿åº¦çå¼ï¼æ以å¦æposition并éå¨Bufferçå¼å§å¤çè¯ï¼è¿åå¼å°ä¸æ¯Bufferçé¿åº¦ï¼èæ¯å¨Bufferä¸å©ä½çå符çé¿åº¦ãæ¢å¥è¯è¯´ï¼ä¸é¢ç¨åºä¸ç循ç¯ä¹å¯ä»¥ä¿®æ¹æè¿æ ·ï¼
ãã
ããCharBuffer buff = CharBuffer.wrap(args[0]);
ãã
ããfor (int i=0; buff.length() 0; i++)
ãã
ãã{System.out.println(buff.get());}
ãã
ããæ们åå°æ£é¢ï¼ç»§ç»è®¨è®ºå¤§å°ï¼sizingï¼åä½ç½®ï¼positioningï¼çå ³ç³»ï¼å¨è¿éï¼æå个æ¦å¿µå¿ é¡»æç¡®ï¼å®ä»¬æ¯markï¼æ è®°ï¼ï¼positionï¼ä½ç½®ï¼ï¼limitï¼éå¶ï¼ï¼åcapacityï¼å®¹éï¼ã· markââç¨markæ¹æ³è®¾ç½®çå¯è®¾ä½ç½®ï¼markæ¹æ³å¯ä»¥ä½¿ç¨resetæ¥éç½®positionï¼<=positionï¼=0ï¼Â· positionââå¨Bufferä¸ç®å读åçä½ç½®ï¼<=limitï¼Â· limitââ第ä¸ä¸ªä¸åºè¯¥è¢«è¯»åçå ç´ çä½ç½®çindexï¼ç´¢å¼å·ï¼ï¼<=cpacityï¼Â· capcityââBufferç大å°ï¼=sizeãPositionï¼ä½ç½®ï¼å±æ§å¼æ¯æ们å¨å¯¹ä¸ä¸ªBuffer读åæè åå ¥çæ¶åéè¦æ¶å»ç¢è®°çä¿¡æ¯ãä¾å¦ï¼å¦æä½ æ³è¯»åä½ åååå ¥çå符ï¼ä½ ä¸è®¸æposition移å¨å°ä½ æ³è¯»åçä½ç½®ï¼å¦åï¼ä½ å°è¶è¿limitçéå¶ï¼è读å°ä¸ä¸ªä¸ç¥éæ¯ä»ä¹çå符ãè¿æ¶åä½ éè¦ç«å»ä½¿ç¨flipæ¹æ³ï¼ælimit移å¨å°å½åçä½ç½®ï¼å¹¶æposition移å¨å°0ä½ç½®ãä½ ä¹å¯ä»¥åç»ä¸ä¸ªbufferæ¥ä¿æå½åçlimitä½ç½®ï¼èæpositionè¿åå°0ä½ç½®ã举个ä¾åï¼å¦æä»ä¸é¢è¿ä¸å°æ®µä»£ç ä¸çflipè°ç¨å»æï¼å°è¿åä¸ä¸ªç©ºç½ï¼å 为å¨bufferä¸è¿ä»ä¹é½æ²¡æã
ã
ããbuff.put('a');
ããbuff.flip();
ããbuff.get();
ããä¸é¢çå°è£ æºå¶æ¯ä¸ä¸ªéç´æ¥ç¼å²ï¼non-direct bufferï¼çä¾åãéç´æ¥ç¼å²ä¹å¯ä»¥éè¿allocateæ¹æ³æ¥å建åéå®å¤§å°ï¼æ¬è´¨ä¸æ¥è¯´ï¼åªæ¯ææ°æ®å°è£ å°ä¸ä¸ªæ°ç»éäºãå¦ææ¿ææ¶èç¨å¾®å¤ä¸ç¹çå建èµæºï¼ä½ ä¹å¯ä»¥éè¿allocateDirectæ¹æ³å¼è¾ä¸åè¿ç»çå åæ¥ä¿åæ°æ®ï¼è¿ä¹å¯ä»¥ç§°ä½ç´æ¥ç¼å²ãç´æ¥ç¼å²æ¯ä¾èµäºç³»ç»çæ¬å°æ¥å£çI/Oæä½æ¥ä¼åååæä½çã
ãã
ããæ件æ å°
ãã
ããMappedByteBufferæ¯ä¸ä¸ªä¸é¨ç¨äºç´æ¥ç¼å²çByteBufferï¼è¿ä¸ªç±»ç¨åèç¼å²æ¥æ å°ä¸ä¸ªæ件ãæ³è¦æ å°ä¸ä¸ªæ件å°MappedByteBufferï¼ä½ å¿ é¡»å åå¾è¿ä¸ªæ件çééï¼channelï¼ãééæ¯æç§å·²å»ºç«çè¿æ¥ï¼ä¾å¦ç®¡éï¼pipeï¼ï¼å¥æ¥å£ï¼socketï¼ï¼æè æ件ï¼fileï¼çè½å¤å®æI/Oæä½ç对象ãå¦ææ¯æ件ééï¼ä½ å¯ä»¥éè¿FileInputStreamï¼æ件è¾å ¥æµï¼ï¼FileOutputStreamï¼æ件è¾åºæµï¼æè RandomAccessFileï¼éæºååæ件ï¼çgetChannelæ¹æ³æ¥è·å¾ä¸ä¸ªééãä¸æ¦ä½ åå¾è¿ä¸ªééï¼ä½ å°±å¯ä»¥éè¿å®çmapæ¹æ³ï¼æææ å°æ¨¡å¼æ¥æä½ æ³æ å°çé£ä¸é¨åæ件æ å°å°ç¼å²ä¸å»ãæ件ééå¯ä»¥ä½¿ç¨FileChannel.MapModeçä»»ä¸ä¸ªå¸¸æ°æå¼ï¼åªè¯»ï¼READ_ONLYï¼ï¼ç§æ/åæ¶æ·è´ï¼PRIVATEï¼ï¼æè 读åï¼READ_WRITEï¼ãä¸é¢æ¯ä¸ä¸ªä»æ件ä¸å建åªè¯»çMappedByteBufferçåºæ¬ä¾ç¨ï¼
ãString filename = ...;
ãã
ããFileInputStream input = new FileInputStream(filename);
ãã
ããFileChannel channel = input.getChannel();
ãã
ããint fileLength = (int)channel.size();
ãã
ããMappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);
ãã
ããä½ å¯ä»¥å¨java.nio.channelså éæ¾å°ä¸ééæå ³çç±»ãä¸æ¦MappedByteBuffer被建ç«äºï¼ä½ å°±å¯ä»¥è±¡ååå ¶å®ä»»ä½ByteBufferä¸æ ·æ¥æä½å®ãå½ç¶å¨è¿ä¸ªä¾åéå®æ¯åªè¯»çï¼æ以å å ¥ä½ è¯å¾åå ¥ä¸äºä¸è¥¿çæ¶åï¼å®ä¼æåºä¸ä¸ªNonWritableChannelExceptionçå¼å¸¸ãåå¦ä½ æ³æå®å½ä½å符æ¥å¤ççè¯ï¼ä½ å¿ é¡»å¶å®ä¸ä¸ªå符éæByteBuffer转åæCharBufferãè¿ä¸ªå符éæ¯å¨Charsetç±»ä¸å®ä¹çãç¶åä½ ç¨CharsetDecoder类对æ件çå 容è¿è¡è§£ç ãå®ç¸åçæä½æ¯ç±CharsetEncoderç±»æ¥å®æçã
ãã
ããã
ãã// ISO-8859-1 æ¯ISOæä¸å符表#1Charset
ãã
ããcharset = Charset.forName("ISO-8859-1");
ãã
ããCharsetDecoder decoder = charset.newDecoder();
ãã
ããCharBuffer charBuffer = decoder.decode(buffer);
ãã
ã
ããè¿ä¸ªç±»å¯ä»¥å¨java.nio.charsetå ä¸æ¾å°ã
ãã
ãã
ããæ£å表达å¼
ãã
ããä¸æ¦ä½ å®æäºä»æ件å°CharBufferçå¯è¾å ¥æ å°ï¼ä½ å°±å¯ä»¥å¯¹æ件å 容è¿è¡æ¨¡å¼å¹é ãå°±åæ们åå«ä½¿ç¨grepå½ä»¤åwcå½ä»¤æ¥è¿è¡æ£å表达çå¹é ååè¯è®¡æ°ä¸æ ·ãå ¶ä¸ä½¿ç¨å°äºjava.util.regexä¸çPatternåMatcher两个类ãPattern类为å¹é æ£å表达æä¾äºææçæé ç±»åãä¸è¬æ¥è¯´ï¼ä½ ç模å¼è¡¨è¾¾æ¯ä¸ä¸ªå符串ï¼å¯ä»¥æ¥é ç±»ææ¡£å¾å°æ¨¡å¼çå®æ´ç»èï¼è¿éåªæä¾ä¸äºç®å常ç¨çä¾åï¼Â· è¡æ¨¡å¼ï¼ä»»æ个å符ç¶å以å车æ¢è¡å宿并ä¸/æè è¡ç»æï¼.* ?æ.*$ · è¿ç»çæ°åï¼[0-9]* æè d*· ä¸ä¸ªæ§å¶ç¬¦ï¼{cntrl}· ä¸ä¸ªå¤§åæè å°åUS-ASCIIå符ï¼æ¥çä¸ä¸ªç©ºæ ¼ï¼æ¥çæ ç¹ï¼[p{Lower}p{Upper}]sp{Punct}注ï¼ä¸å¹¸çæ¯ï¼J2SE 1.4 beta3ä¸ææäºè¿ä¸åï¼å 为å®å¯¹æ£å表达å¼æå¿ é¡»çå符ç¼å²ç次åºæ¯æçé常ä¸å¥½ãä»SUNçBug Paradeå¯ä»¥çå°è¿ä¸ªé®é¢ç详ç»èµæï¼å¸æä½ æJDCçå¸å·ï¼åµåµï¼æ²¡æ就快å»ç³è¯·åï¼è¿æ£çå¹²ä»ä¹ï¼ï¼ãå¾éæ¾ï¼è¿æå³çä½ ä¸è½ç¨æ¨¡å¼å¹é åæ¶å»è¯»åä¸ä¸ªè¯æè ä¸è¡ãå¦ææ³è·å¾æ´å¤çæå ³æ£å表达å¼åºçä¿¡æ¯ï¼å¯ä»¥åèæ¬ææåæåâèµæºâä¸çãRegular Expressions and the Java Programming Languageãï¼æ£å表达åjavaç¼ç¨è¯è¨ï¼
ãã
ããå¥æ¥å£éé
ãã
ãã
ããä¸é¢æ们è¦ä»æ件éé转移å°è¯»åä¸ä¸ªå¥æ¥å£è¿æ¥çééä¸æ¥ãè¿ä¸ªééå¯ä»¥ç¨åé»å¡æ¨¡å¼ï¼ä¹å¯ä»¥ç¨ä½éé»å¡æ¨¡å¼ãå¦ææ¯é»å¡æ¨¡å¼ï¼åå³äºä½ çç¨åºæ¯æå¡å¨ç«¯è¿æ¯å®¢æ·ç«¯ï¼åªéæä½ çè°ç¨æ¢æconnectæè acceptãèå¨éé»å¡æ¨¡å¼ï¼å®ä»¬çå¤çæ¹å¼æ¯ä¸ä¸æ ·çãè¿äºæ°ç±»å¤çåºæ¬å¥æ¥å£ç读åæä½ãå¨java.netå ä¸çInetSocketAddressç±»æå®è¿æ¥å°åï¼java.nio.channelså ä¸çSocketChannelç±»æ¥å®æå®é ç读åæä½ã使ç¨InetSocketAddressæ¥è¿è¡è¿æ¥é常类似äºæ®éçSocketç±»çæä½ãä½ æè¦åçä¸åä» ä» æ¯æä¾ä¸»æºå端å£å·ï¼
ãã
ãString host = ...;
ãã
ããInetSocketAddress socketAddress = new InetSocketAddress(host, 80);
ãã
ããä¸æ¦ä½ è·å¾äºInetSocketAddressï¼ä¸åé½æ¹åäºï¼æä¹å¬ç象童è¯^&^ï¼ãä½ å¯ä»¥æå¼ä¸ä¸ªSocketChannelæ¥è¿æ¥å°InetSocketAddressï¼ç¨å®æ¥å代æ们以åä»å¥æ¥å£çè¾å ¥æµæ¥è¯»åãåå¥æ¥å£çè¾åºæµåå ¥çæææä½ï¼
ãã
ããSocketChannel channel = SocketChannel.open();
ãã
ããchannel.connect(socketAddress);
Â