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

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

JDK1.4新特性之I/O APIs篇

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

  前些天碰到比爾,你看他皺著眉頭,一定又碰到了什么難題。一問,還真讓我猜中了。原來,比爾對java中的一些新概念還不太理解,不知道該怎么用。其實,碰到什么難題,可以去找人問,和別人討論嘛。于是我把比爾領到了“開發者聯盟”,相信他會在那得到“前輩”的幫助.現在,就讓我們來看看,比爾究竟碰到了什么難題。
  
  了解Java的人一定對于Java中的I/O APIs很熟悉,這里不想對此多費口舌,而是希望向大家介紹一下JDK1.4中新的I/O APIs,讓大家都能了解這些新特性,盡早用最先進的裝備來武裝自己,以免豪華的法拉利跑車總是跑在痛苦的泥濘路上。
  
  當然閱讀本文之前,你最好先了解一下原有的Java I/O APIs。
  新在何處
  任何新事物的出現,都是對舊事物的一種修正和改進,從而使其更加方便可用,在J2SE v1.4中出現的新I/O(NIO) APIs亦是如此,主要是針對那些舊的I/O APIs不能解決或者解決起來很麻煩的問題。這些新特性主要體現在以下幾個方面:
  · 更加靈活的可伸縮的I/O接口(scalable I/O),包括I/O抽象Channels的出現以及新的多元的(multiplexed),非阻塞(non-blocking)的I/O機制。這使得構建產品級的應用服務更加方便靈活,使你能夠輕松應付成千上萬個開放的連接,并且可以有效地利用多個處理器。
  
  · 快速緩存(fast buffered)的二進制和字符I/O接口。快速緩存的二進制I/O API使得你可以很輕易地編寫出操作文件流或者二進制數據流的高性能代碼。而快速緩存的字符I/O API使得你可以更加高效地處理字符流和文件,此外它還將正則表達式引入到Java平臺中來格式化你的輸入輸出。
  
  · 字符集的編碼器和解碼器(Character-set encoders and decoders)。這些字符集轉換API使得我們可以直接訪問操作系統內置的字符集轉換器,同時還支持那些外來的轉化器。
  
  · 基于Perl風格正則表達式的模式匹配機制(A pattern-matching facility based on Perl-style regular eXPRessions)。
  
  · 改良的文件系統接口,支持鎖定和內存映射(locks and memory mapping)。該特性使得你可以更加輕易地處理各種文件系統操作中出現的問題,同時使得你可以更加高效地訪問大量的文件屬性集。此外假如你確實需要,你還可以訪問與平臺相關的一些特性。最后,它還提供對非本地文件系統的支持,比如網絡文件系統(network filesystems)。
  
  · 新的I/O違例類可以使你更加有針對性地來處理各種I/O錯誤,讓你能夠在各種平臺上一致地來對待這些錯誤。
  
  · 增加了對并發的支持,NIO類中的大部分方法都支持多個并發的線程。
  新的包(packages),類(classes)和接口(interfaces)
  為了實現上面提到的那些功能,在Java JDK1.4中新增加以下這些部分來提供支持:
  · java.nio包:主要是和Buffers有關的一些類
  · java.nio.channels包:主要包括Channels和selectors
  
  · java.nio.charset包:和字符集有關的類
  
  · java.nio.channels.spi包:提供channels服務的類
  
  · java.nio.charset.spi包:提供charsets服務的類
  
  · java.util.regex包:主要是利用正則表達式進行模式匹配的類
  
  · java.lang.CharSequence接口:主要是為java.util.regex包中的一些方法提供一個統一的接口。類String,StringBuffer,java.nio.CharBuffer都重新實現了該接口。
  
  除了這些新增加的類以外,許多原有的類和接口也做了相應的改變。比如FileInputStream和FileOutputStream類中的getChannel、close方法,RandomaccessFile中的getChannel方法等。(1)
  幾點說明
  這些新的I/O APIs的推出,并不意味著原有的I/O APIs的廢棄,盡管我們提倡以后盡量使用NIO APIs中的特性。另外,雖然這些NIO APIs都希望做到完全的平臺無關性,但是由于I/O工作的非凡性,有些特性還是對操作系統和硬件平臺有很大的依靠性,比如可升級的I/O API(scalable I/O API),二進制I/O API(binary I/O API)和新的文件系統接口(new filesystem interface)。所以我們以后在利用這些NIO APIs的時候,應當盡量減少本地代碼的部分,做到最大限度的可移植性。
  一些例子
  
  
  介紹完這些新特性以后,我想大家都迫切希望能夠通過具體的實例來看看它們具體的用法,可不能光說不練。但是,要知道整個NIO APIs涵蓋太大的范圍,要一個個完整地講解它們可能需要一本厚厚的書。所以我們今天只想通過一個典型的例子來做一個引導性的講解,更多的工作需要大家以后在具體的實際編程過程中慢慢學習。
  
  為了方便,我將直接采用Sun Java的例子程序,這個例子包括兩個文件:TimeQuery.java和TimeServer.java。前者可以向一系列主機查詢時間,后者監聽連接并且告訴呼叫者確切的時間。這是個演示NIO socket channels,緩存治理(buffer handling),字符集和正則表達式的很好的例子。(2)
  
  首先,讓我們來看看TimeServer.java(具體代碼見清單一)。該程序首先檢查參數是否是一個數字串,注重這里模式匹配的用法。
  
  if ((args.length == 1) && Pattern.matches("[0-9]+", args[0]))
   port = Integer.parseInt(args[0]);
  
  
  
  接著在方法setup()中,調用類ServerSocketChannel的靜態方法open()建立一個server-socket channel,此時它還并沒有和具體的主機和端口綁定起來,此時我們需要利用到相關聯的server socket的bind()方法,server socket可以用類ServerSocketChannel的socket()方法得到。
  
  ServerSocketChannel ssc = ServerSocketChannel.open();
  InetSocketAddress isa
   = new InetSocketAddress(InetAddress.getLocalHost(), port);
  ssc.socket().bind(isa);
  
  
  
  最后,監聽服務請求的任務在方法serve()中實現。首先,調用類ServerSocketChannel的方法accept()接受連接并返回一個SocketChannel對象,接著調用該對象的write()方法向channel中寫入數據。注重在數據寫入之前對它的處理過程。
  
  SocketChannel sc = ssc.accept();
   String now = new Date().toString();
   sc.write(encoder.encode(CharBuffer.wrap(now + "/r/n")));
  /********************清單一:TimeServer.java完整的程序清單********************/
  /*
   * @(#)TimeServer.java 1.3 01/12/13
   * Listen for connections and tell callers what time it is.
   * Demonstrates NIO socket channels (accepting and writing),
   * buffer handling, charsets, and regular expressions.
   *
   * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved.
   */
  import java.io.*;
  import java.net.*;
  import java.nio.*;
  import java.nio.channels.*;
  import java.nio.charset.*;
  import java.util.*;
  import java.util.regex.*;
  public class TimeServer
  {
   // We can't use the normal daytime port (unless we're running as root,
   // which is unlikely), so we use this one instead
   private static int PORT = 8013;
   // The port we'll actually use
   private static int port = PORT;
   // Charset and encoder for US-ASCII
   private static Charset charset = Charset.forName("US-ASCII");
   private static CharsetEncoder encoder = charset.newEncoder();
   // Direct byte buffer for writing
   private static ByteBuffer dbuf = ByteBuffer.allocateDirect(1024);
   // Open and bind the server-socket channel
   //
   private static ServerSocketChannel setup() throws IOException
   {
   ServerSocketChannel ssc = ServerSocketChannel.open();
   InetSocketAddress isa
   = new InetSocketAddress(InetAddress.getLocalHost(), port);
   ssc.socket().bind(isa);
   return ssc;
   }
   // Service the next request to come in on the given channel
   //
   private static void serve(ServerSocketChannel ssc) throws IOException
   {
   SocketChannel sc = ssc.accept();
   try
   {
   String now = new Date().toString();
   sc.write(encoder.encode(CharBuffer.wrap(now + "/r/n")));
   System.out.println(sc.socket().getInetAddress() + " : " + now);
   sc.close();
   }
   finally
   {
   // Make sure we close the channel (and hence the socket)
   sc.close();
   }
   }
  
   public static void main(String[] args) throws IOException
   {
   if (args.length > 1)
   {
   System.err.println("Usage: java TimeServer [port]");
   return;
   }
  
   // If the first argument is a string of digits then we take that
   // to be the port number
   if ((args.length == 1) && Pattern.matches("[0-9]+", args[0]))
   port = Integer.parseInt(args[0]);
  ServerSocketCh

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 托里县| 张家口市| 龙川县| 颍上县| 嘉义市| 汉沽区| 饶平县| 班玛县| 阿拉善左旗| 修武县| 内江市| 安多县| 德钦县| 个旧市| 白水县| 商都县| 沙河市| 石门县| 新绛县| 民勤县| 通城县| 会昌县| 绥德县| 金昌市| 台北县| 克拉玛依市| 巴林左旗| 上蔡县| 湖北省| 伊金霍洛旗| 揭西县| 高安市| 扎囊县| 如皋市| 阿拉善右旗| 贵州省| 鄯善县| 海门市| 乌海市| 张家口市| 玉屏|