国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

J2SE1.4的I/O新特性

2019-11-18 11:55:55
字體:
來源:轉載
供稿:網友

  譯者序:這是一篇比較使用的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);
  
  
  
  在連接完成之后,你馬上可以使用By

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 浮梁县| 新建县| 南丰县| 固阳县| 观塘区| 通河县| 区。| 东阿县| 朝阳市| 万源市| 无极县| 简阳市| 额敏县| 甘南县| 延川县| 卓尼县| 甘洛县| 都安| 花垣县| 山阴县| 化德县| 石门县| 新绛县| 鄂托克前旗| 德安县| 石渠县| 清镇市| 岳西县| 广汉市| 六枝特区| 石嘴山市| 合肥市| 襄汾县| 宾川县| 蒲城县| 商河县| 黑水县| 瑞丽市| 彩票| 元氏县| 离岛区|