`

Java nio(二)

阅读更多
一、各种缓冲区:
所有的缓冲区都继承了Buffer,Buffer类定义了所有缓冲区共有的基本特征,缓冲区存储了制定类型的元素序列有:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。
我们需要知道这些基本类型占用存储空间与Byte的对应关系:
char 2 bytes,int 4 bytes,double 8 bytes
二、我们看看Buffer三个重要的概念以及他们之间的关系:
capacity 所能存方特定类型值得最大数量
limit 第一个不能读取或写入的索引位置
position 下一个要读取或写入的缓冲区索引位置
理解这三者的关系是对缓冲区操作的关键:
新创建的一个缓冲区,position=0,limit=capacity
我们可以通过position(int newPosition)和limit(int newLimit)来调整position和limit的值。显然0 =< position =< limit =< capacity,所以我们在设置这个位置
需要小心,以满足这个条件,一般如果同时设置limit和position的时候,下面代码是一个
安全的方法:
buf.position(0).limit(newLimit).position(newPosition);

position和capacity存在的理由不需要解释。


为什么需要limit呢?这是理解缓冲区操作的关键所在。
一段数据怎么去标示出来呢?两个点决定了一个段啊,
而position就是起点,limit就是终点。但这个起点和终点在不同时候,他
表示的含义不同:
当把数据写入buffer时,poision到limit就是可以写的空间
当从buffer读数据时,position到limit就是可读取的数据
所以我们经常做的事情就是:
把数据写入Buffer,,然后使用buf.flip()操作,最后把Buffer写入File中。这个过程发生了什么?
我们把数据写入Buffer后,position为写入的最后一个数据的位置,而buf.flip()是
buf.limit(buf.position()).position(0);的简写形式。这样position到limit就
标示了可以写到文件的数据


另外还有一个mark()方法,他记录了上一次position和limit的位置,通过reset()可以
恢复到这个状态。
三、下面我们看看如何创建缓冲区的:
缓冲区类没有共有的构造方法,但提供了静态工厂方法allocate来创造缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
FloatBuffer buf = FloatBuffer.allocate(100);
//...

我们可以通过wrap来把字节数组包装成ByteBuffer
 String str = "Hi,just a test";
 byte[] arr = str.getBytes();
 ByteBuffer buf = ByteBuffer.wrap(arr);
 //ByteBuffer buf = ByteBuffer.wrap(arr,offset,len);

四、视图缓存区:
从名字我们可以知道这种缓冲区是为了提供方便操作的视图而存在的,从ByteBuffer可以
得到各种基本类型(boolean除外)对应的缓冲区,这个过程是通过asXxBuffer()方法得到的。
有了视图缓冲区我们就可以方便的对缓冲区进行操作了,所做的操作直接影响后备缓冲区(ByteBuffer)的数据,但不影响后备缓冲区的limit和position.所以我们如果这时候
在想把后备缓冲区写入文件的时候,需要手工调整limit值。
五、缓冲区数据的传送:
1、将数据送到缓冲区:
ByteBuffer有两种put操作(相对的和决对的),用来传送数据到缓冲区:
put(byte b);
put(int index,byte b);
put(byte[] array,int offset,int len);
put(ByteBuffer src);

例子:
 String text = "Value of e";
 ByteBuffer buf = ByteBuffer.allocate(text.length() + sizeof(Math.E));
 buf.put(text.getBytes()).putDouble(Math.E);

这个例子会用本地的编码获的字节数组。
而如果要想以原来Unicode字符码的形式传递的话,可以这么写:
 char[] array = text.toCharArray();
 ByteBuffer buf = ByteBuffer.allocate(50);
 for(char ch : array)
   buf.putChar(ch);
 buf.putDouble(Math.E);

六、写文件
我们把数据写入缓冲区和上次我们总结的用Channel把缓冲区的数据写入文件合起来就可以写文件了:
 String text = "Value of e";
 ByteBuffer buf = ByteBuffer.allocate(text.length() + sizeof(Math.E));
 buf.put(text.getBytes()).putDouble(Math.E);
 buf.flip();
 File file = new File("D:\test.txt");
 FileOutputStream fos = new FileOutputStream(file);
 FileChannle outputChannel = fos.getChannel();
 outputChannel.write(buf);
 fos.close();

六、使用视图缓冲区:
前面我们介绍了视图缓冲区,我们看看使用视图缓冲区写文件的例子:
 String greeting = "Hi,nice to meet you!";
 ByteBuffer buf = ByteBuffer.allocate(1024);
 CharBuffer charBuf = buf.asCharBuffer();//得到试图缓冲区
 charBuf.put(greeting);//把字符串转换成Buffer,操作视图缓冲区
 buf.limit(2*charBuffer.position());
 FileChannel outputChannel = fos.getChannel();
 fos.write(buf);
 fos.close();

七、集中写操作:
文件通道有两个方法可以执行集中写操作:
write(ByteBuffer[] buffers);
write(ByteBuffer[] buffers,int offset,int length);
把分散在多个buffer的数据集中写入文件
我们看一个例子:
String str = "hi,just a test";
dobule d = Math.E;
FileChannel outputChannel = fos.getChannel();
ByteBuffer[] buffers = new ByteBuffer[2];
buffer[0] = ByteBuffer.allocate(str.length());
buffer[1] = ByteBuffer.allocate(sizeof(i));
buffer[0].put(str.getBytes).flip();
buffer[1].putDouble(d);
outputChannel.write(buffers);
fos.close();




5
2
分享到:
评论
2 楼 youfengkai 2011-10-04  
CharBuffer : 字符缓冲区
1 楼 fuliang 2008-03-02  
补充一个使用视图缓冲区的例子:
通过视图缓冲区,把数据写入缓冲区中,然后写入文件中
public static void testViewBuffer()throws Exception{
      String str = "Hi,just a test";
      ByteBuffer bb = ByteBuffer.allocate(str.length() * 2);
      CharBuffer cb = bb.asCharBuffer();
      cb.put(str);
      bb.limit(cb.position() * 2);
      FileOutputStream fos = new FileOutputStream(new File("D:/a.txt"));
      FileChannel outputChannel = fos.getChannel();
      outputChannel.write(bb);
      fos.close();
    }

读取刚才写入的内容,并得到视图缓冲区,在控制台输出结果:
    public static void testReadViewBufferWritten()throws Exception{
    	ByteBuffer bb = ByteBuffer.allocate(100);
    	FileInputStream fis = new FileInputStream(new File("D:/a.txt"));
    	FileChannel inputChannel = fis.getChannel();
    	inputChannel.read(bb);
    	bb.flip();
    	CharBuffer cb = bb.asCharBuffer();
    	for(int i = 0; i < cb.limit();i++)
    		System.out.print(cb.charAt(i));
          fis.close();
    }

相关推荐

    JavaNIO chm帮助文档

    Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) ...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    java NIO.zip

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    java nio 包读取超大数据文件

    #### 二、Java NIO关键组件 Java NIO的核心组件包括: - **Channels**:用于表示IO源或目标的一个连接点。 - **Buffers**:用来存储数据的对象,是数据传输的载体。 - **Selectors**:多路复用器,用于监控多个...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在传统的Java IO模型中,读写操作是阻塞的,即当调用read或write方法时,线程会等待数据准备好或...

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    Java NIO Socket基本

    Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...

    java nio 实现socket

    #### 二、Java NIO的核心组件 Java NIO的核心组件主要包括以下几种: 1. **Channels(通道)**:通道类似于流(Streams),但它们是双向的,支持读写操作。主要的通道类型有`FileChannel`、`SocketChannel`等。 2. *...

    Java NIO测试示例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...

Global site tag (gtag.js) - Google Analytics