电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

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


发布日期:2022/12/3
 

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

作者:

Merlin 的魔力

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

英文原文

内容:

缓沖区基础

缓沖区类型

直接 vs 间接

内存映射文件

结束语

参考资料

关于作者

对本文的评价

相关内容

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

Working XML: Wrestling with Java NIO

T彻底转变流 部分优化 Java 内部 I/O

Merlin的魔力

developerWorks Toolbox subscription

在 Java 专区还有

工具与产品

代码与组件

所有文章

实用技巧

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

级别初级

John Zukowski

总裁JZ Ventures 公司

Merlin 的魔力

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

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

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

类(NIO)现在这些类位于

javanio

包中

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

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

参考资料

缓沖区基础

抽象的

Buffer

javanio

包支持缓沖区的基础

Buffer

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

RandomAccessFile

RandomAccessFile

一样使用

Buffer

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

Buffer

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

capacity()

表明缓沖区的大小

limit()

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

:limit(int newLimit)

来改变这个限制

position()

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

mark()

为了稍后用

reset()

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

缓沖区的基本操作是

get()

put()

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

flip()

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

清单 读/写示例

import javanio*;

CharBuffer buff = ;

buffput(A);

buffflip();

char c = buffget();

Systemoutprintln(An A: + c);

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

Buffer

子类

缓沖区类型

Merlin 具有 种特定的

Buffer

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

boolean)

ByteBuffer

CharBuffer

DoubleBuffer

FloatBuffer

IntBuffer

LongBuffer

ShortBuffer

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

MappedByteBuffer

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

ByteBuffer

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

Object

或其它任何类型

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

get()

put()

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

get()

put()

方法例如有了

CharBuffer

可以用

get()

获得下一个字符

get(int index)

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

get(char[] destination)

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

CharBuffer

为例

CharBufferwrap(aString)

可以将

String

对象转换成

CharBuffer

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

CharBuffer

并显示参数中的每个字符

清单 CharBuffer 演示

import javanio*;

public class ReadBuff {

public static void main(String args[]) {

if (argslength != ) {

CharBuffer buff = CharBufferwrap(args[]);

for (int i= n=bufflength(); i

请注意这里我使用了

get()

而没有使用

get(index)

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

get()

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

直接 vs 间接

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

ByteBuffer

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

Buffer

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

中代码的行为与清单 的行为一样但清单 使用直接缓沖区

清单 列出网络接口

import javanio*;

public class ReadDirectBuff {

public static void main(String args[]) {

if (argslength != ) {

String arg = args[];

int size = arglength();

ByteBuffer byteBuffer = ByteBufferallocateDirect(size*);

CharBuffer buff = byteBufferasCharBuffer();

buffput(arg);

buffrewind();

for (int i= n=bufflength(); i

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

String

包装在直接

ByteBuffer

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

size*

内存映射文件

Buffer

MappedByteBuffer

只是一种特殊的

ByteBuffer

MappedByteBuffer

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

Buffer

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

javaniochannelsFileChannel

map()

方法来获取

MappedByteBuffer

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

getChannel()

方法从

FileInputStream

FileOutputStream

FileChannel

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

MappedByteBuffer

上一篇:网友杂谈各种app Server

下一篇:Swinghacks:JTable单击表头选中列