王朝网络
分享
 
 
 

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

王朝java/jsp·作者佚名  2008-05-31
宽屏版  字体: |||超大  

前些天碰到比尔,你看他皱着眉头,一定又碰到了什么难题。一问,还真让我猜中了。原来,比尔对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.java1.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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有