分享
 
 
 

Merlin的魔力:Merlin的新I/O缓冲区的输入和输出

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

Merlin 的魔力:Merlin 的新 I/O 缓冲区的输入和输出

作者:

Merlin 的魔力:

Merlin 的新 I/O 缓冲区的输入和输出

英文原文

内容:

缓冲区基础

缓冲区类型

直接 vs. 间接

内存映射文件

结束语

参考资料

关于作者

对本文的评价

相关内容:

Merlin 给 Java 平台带来了非阻塞 I/O

Working XML: Wrestling with Java NIO

T彻底转变流,第 2 部分:优化 Java 内部 I/O

Merlin的魔力

developerWorks Toolbox subscription

在 Java 专区还有:

工具与产品

代码与组件

所有文章

实用技巧

了解如何操作 J2SE 1.4 的新 I/O 包

级别:初级

John Zukowski

jaz@zukowski.net

总裁,JZ Ventures 公司

2003 年 6 月

Merlin 的魔力

中,常驻 Java 编程专家 John Zukowski 展示了如何操作那些数据缓冲区来执行如读/写原语这样的任务以及如何使用内存映射文件。在以后的文章里,他将把这里所提到的概念扩展到套接字通道的使用。

Java 2 平台标准版(Java 2 Platform Standard Edition,J2SE)1.4 对 Java 平台的 I/O 处理能力做了大量更改。它不仅用流到流的链接方式继续支持以前

J2SE 发行版的基于流的 I/O 操作,而且 Merlin 还添加了新的功能 ― 称之为新 I/O

类(NIO),现在这些类位于

java.nio

包中。

I/O 执行输入和输出操作,将数据从文件或系统控制台等传送至或传送出应用程序。(有关

Java I/O 的其它信息,请参阅

参考资料

缓冲区基础

抽象的

Buffer

java.nio

包支持缓冲区的基础。

Buffer

的工作方式就象内存中用于读写基本数据类型的

RandomAccessFile

RandomAccessFile

一样,使用

Buffer

,所执行的下一个操作(读/写)在当前某个位置发生。执行这两个操作中的任一个都会改变那个位置,所以在写操作之后进行读操作不会读到刚才所写的内容,而会读到刚才所写内容之后的数据。

Buffer

提供了四个指示方法,用于访问线姓结构(从最高值到最低值):

capacity()

:表明缓冲区的大小

limit()

:告诉您到目前为止已经往缓冲区填了多少字节,或者让您用

:limit(int newLimit)

来改变这个限制

position()

:告诉您当前的位置,以执行下一个读/写操作

mark()

:为了稍后用

reset()

进行重新设置而记住某个位置

缓冲区的基本操作是

get()

put()

;然而,这些方法在子类中都是针对每种数据类型的特定方法。为了说明这一情况,让我们研究一个简单示例,该示例演示了从同一个缓冲区读和写一个字符。在清单

1 中,

flip()

方法交换限制和位置,然后将位置置为 0,并废弃标记,让您读刚才所写的数据:

清单 1. 读/写示例

import java.nio.*;

...

CharBuffer buff = ...;

buff.put('A');

buff.flip();

char c = buff.get();

System.out.println("An A: " + c);

现在让我们研究一些具体的

Buffer

子类。

缓冲区类型

Merlin 具有 7 种特定的

Buffer

类型,每种类型对应着一个基本数据类型(不包括

boolean):

ByteBuffer

CharBuffer

DoubleBuffer

FloatBuffer

IntBuffer

LongBuffer

ShortBuffer

在本文后面,我将讨论第 8 种类型

MappedByteBuffer

,它用于内存映射文件。如果您必须使用的类型不是这些基本类型,则可以先从

ByteBuffer

获得字节类型,然后将其转换成

Object

或其它任何类型。

正如前面所提到的,每个缓冲区包含

get()

put()

方法,它们可以提供类型安全的版本。通常,需要重载这些

get()

put()

方法。例如,有了

CharBuffer

,可以用

get()

获得下一个字符,用

get(int index)

获得某个特定位置的字符,或者用

get(char[] destination)

获得一串字符。静态方法也可以创建缓冲区,因为不存在构造函数。那么,仍以

CharBuffer

为例,用

CharBuffer.wrap(aString)

可以将

String

对象转换成

CharBuffer

。为了演示,清单 2 接受第一个命令行参数,将它转换成

CharBuffer

,并显示参数中的每个字符:

清单 2. CharBuffer 演示

import java.nio.*;

public class ReadBuff {

public static void main(String args[]) {

if (args.length != 0) {

CharBuffer buff = CharBuffer.wrap(args[0]);

for (int i=0, n=buff.length(); i

请注意,这里我使用了

get()

,而没有使用

get(index)

。我这样做的原因是,在每次执行

get()

操作之后,位置都会移动,所以不需要手工来声明要检索的位置。

直接 vs. 间接

既然已经了解了典型的缓冲区,那么让我们研究直接缓冲区与间接缓冲区之间的差别。在创建缓冲区时,可以要求创建直接缓冲区,创建直接缓冲区的成本要比创建间接缓冲区高,但这可以使运行时环境直接在该缓冲区上进行较快的本机 I/O 操作。因为创建直接缓冲区所增加的成本,所以直接缓冲区只用于长生存期的缓冲区,而不用于短生存期、一次姓且用完就丢弃的缓冲区。而且,只能在

ByteBuffer

这个级别上创建直接缓冲区,如果希望使用其它类型,则必须将

Buffer

转换成更具体的类型。为了演示,清单

3 中代码的行为与清单 2 的行为一样,但清单 3 使用直接缓冲区:

清单 3. 列出网络接口

import java.nio.*;

public class ReadDirectBuff {

public static void main(String args[]) {

if (args.length != 0) {

String arg = args[0];

int size = arg.length();

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(size*2);

CharBuffer buff = byteBuffer.asCharBuffer();

buff.put(arg);

buff.rewind();

for (int i=0, n=buff.length(); i

在上面的代码中,请注意,不能只是将

String

包装在直接

ByteBuffer

中。必须首先创建一个缓冲区,先填充它,然后将位置倒回起始点,这样才能从头读。还要记住,字符长度是字节长度的两倍,因此示例中会有

size*2

内存映射文件

第 8 种

Buffer

MappedByteBuffer

只是一种特殊的

ByteBuffer

MappedByteBuffer

将文件所在区域直接映射到内存。通常,该区域包含整个文件,但也可以只映射部分文件。所以,必须指定要映射文件的哪部分。而且,与其它

Buffer

对象一样,这里没有构造函数;必须让

java.nio.channels.FileChannel

map()

方法来获取

MappedByteBuffer

。此外,无需过多涉及通道就可以用

getChannel()

方法从

FileInputStream

FileOutputStream

FileChannel

。通过从命令行传入文件名来读取文本文件的内容,清单 4 显示了

MappedByteBuffer

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有