`

【NIO】Chapter 2. Buffers

    博客分类:
  • Java
 
阅读更多

 

Buffer Basics

Attributes

Capacity

The maximum number of data elements the buffer can hold.

The capacity is set when the buffer is created and can never be changed. 

指定缓冲区总容量,在分配缓冲区时指定

Limit

The first element of the buffer that should not be read or written.

In other words, the count of live elements in the buffer. 

指定有多少元素可读,或者多少空间可写

Postion

The index of the next element to beread or written.

The position is updated automatically by relative get()and put()methods. 

指定下一个可读的元素,或者下一个可写的位置

Mark

A remembered position. Calling mark()sets mark= position.

Calling reset() sets position= mark. The mark is undefined until set. 

标记缓冲区某个位置

 

4个属性的大小关系比较:

0 <= mark <= position <= limit <= capacity

 

新建缓冲区的初始状态:

 

API

Super Class

package java.nio; 
public abstract class Buffer { 
public final int capacity() 
public final int position() 
public final Buffer position (int newPosition) 
public final int limit() 
public final Buffer limit (int newLimit) 
public final Buffer mark() 
public final Buffer reset() 
public final Buffer clear() 
public final Buffer flip() 
public final Buffer rewind() 
public final int remaining() 
public final boolean hasRemaining() 
public abstract boolean isReadOnly(); 
}

 

Invocation chaining

buffer.mark().position(5).reset();

 

Filling

buffer.put((byte)'H').put((byte)'e').put((byte)'l').put((byte)'l').put((byte)'o');

 

buffer.put(0, (byte)'M').put((byte)'w'); 

 

Filpping

buffer.limit(buffer.position()).position(0);

 equal to

buffer.flip(); 

 

Draining

thread-safe

for (int i = 0; buffer.hasRemaining(), i++) { 
myByteArray [i] = buffer.get(); 
} 

 

 not thread-safe:

int count = buffer.remaining(); 
for (int i = 0; i < count, i++) { 
myByteArray [i] = buffer.get(); 
} 

Buffers are not thread-safe.

If you want to access a given buffer concurrently from multiple threads, you'll need to do your own synchronization.

(e.g., acquiring a lock on the buffer object) prior to accessing the buffer. )

 

Clear

Once a buffer has been filled and drained, it can be reused.

The clear()method resets a buffer to an empty state.

It doesn't change any of the data elements of the buffer but simply sets the limit to the capacity and the position back to 0.

This leaves the buffer ready to be filled again.

 

package com.java.nio;

import java.nio.CharBuffer;

public class BufferFillDrain {
	public static void main(String[] argv) throws Exception {
		CharBuffer buffer = CharBuffer.allocate(100);
		while (fillBuffer(buffer)) {
			buffer.flip();
			drainBuffer(buffer);
			buffer.clear();
		}
	}

	private static void drainBuffer(CharBuffer buffer) {
		while (buffer.hasRemaining()) {
			System.out.print(buffer.get());
		}
		System.out.println("");
	}

	private static boolean fillBuffer(CharBuffer buffer) {
		if (index >= strings.length) {
			return (false);
		}
		String string = strings[index++];
		for (int i = 0; i < string.length(); i++) {
			buffer.put(string.charAt(i));//Not effecient!
		}
		return (true);
	}

	private static int index = 0;
	private static String[] strings = { "A random string value",
			"The product of an infinite number of monkeys",
			"Hey hey we're the Monkees",
			"Opening act for the Monkees: Jimi Hendrix",
			"'Scuse me while I kiss this fly", // Sorry Jimi ;-)
			"Help Me! Help Me!", };
}
 

 

Compating

Occasionally, you may wish to drain some, but not all, of the data from a buffer, then
resume filling it. To do this, the unread data elements need to be shifted down so that the
first element is at index zero. While this could be inefficient if done repeatedly, it's
occasionally necessary, and the API provides a method, compact(), to do it for you. The
buffer implementation can potentially copy the data much more efficiently than you
could by using the get()and put()methods. So if you have a need to do this, use
compact().

 

If you want to drain the buffer contents after compaction, the buffer will need to be
flipped as discussed earlier.

 

 

buffer.compact()
 

 

Mark

The clear()method makes a buffer empty,

while reset()returns the position to a previously set mark.

 

 

Bulk Moves

The design goal of buffers is to enable efficient data transfer.

Moving data elements one at a time,  is not very efficient.

As you can see in the following listing, the BufferAPI provides methods to do bulk moves of data elements in or out of a buffer. 

 

public abstract class CharBuffer 
extends Buffer implements CharSequence, Comparable 
{ 
// This is a partial API listing 
public CharBuffer get (char [] dst) 
public CharBuffer get (char [] dst, int offset, int length) 
public final CharBuffer put (char[] src) 
public CharBuffer put (char [] src, int offset, int length) 
public CharBuffer put (CharBuffer src) 
public final CharBuffer put (String src) 
public CharBuffer put (String src, int start, int end) 
}
 

 

 

buffer.get (myArray); 
 equivalent to

 

 

buffer.get (myArray, 0, myArray.length);
Bulk transfers are always of a fixed size. Omitting the length means that the entirearray will be filled.

 

 

 

char [] bigArray = new char [1000]; 
// Get count of chars remaining in the buffer 
int length = buffer.remaining(); 
// Buffer is known to contain < 1,000 chars 
buffer.get (bigArrray, 0, length); 
// Do something useful with the data 
processData (bigArray, length); 


buffer.put (myArray);
//equivalent to 
buffer.put (myArray, 0, myArray.length); 

dstBuffer.put (srcBuffer); 
//equivalent to 
while (srcBuffer.hasRemaining()) { 
dstBuffer.put (srcBuffer.get()); 
} 


buffer.put (myString); 
//equivalent to
buffer.put (myString, 0, myString.length());

buffer.put (myString, 5, 9);
//equivalent to
for (int i = start; i < end; i++) } 
buffer.put (myString.charAt (i)); 
}
 

 

Creating Buffers

New buffers are created by either allocation or wrapping.

Allocation creates a buffer object and allocates private space to hold capacitydata elements. Wrapping creates a buffer object but does not allocate any space to hold the data elements.

It uses the array you provide as backing storage to hold the data elements of the buffer. 

 

CharBuffer charBuffer = CharBuffer.allocate (100);

//or
//This constructs a new buffer object, but the data elements will live in the array.
//Any change to array will reflect to buffer, reverse the same.
char [] myArray = new char [100]; 
CharBuffer charbuffer = CharBuffer.wrap (myArray); 

 

Buffers created by either allocate()or wrap()are always nondirect.

Nondirect buffers have backing arrays, and you can gain access to those arrays with the remaining API methods listed above.


The boolean method hasArray() tells you if the buffer has an accessible backing array or
not.

If it returns true, the array() method returns a reference to the array storage used by the buffer object. 

If hasArray()returns false, do not call array()or arrayOffset().

 

Direct Buffers

The most significant way in which byte buffers are distinguished from other buffer types
is that they can be the sources and/or targets of I/O performed by Channels.

 

 

 ByteBuffer.allocateDirect()

 

 

ByteBuffer与其它Buffer的最大区别在于,它可以结合Channel进行IO操作

Channel只接收ByteBuffer类型的参数值

 

Direct byte buffers are usually the best choice for I/O operations.

If you will be using the buffer repeatedly in a high-performance scenario, you're better off allocating direct buffers and reusing them.

推荐使用直接缓冲区,并复用它!

 

Direct buffers are optimal for I/O, but they may be more expensive to create than
nondirect byte buffers.

创建直接缓冲区的代价比较高,比在JVM的堆空间创建Buffer更慢。

 

到底使用直接缓冲区还是使用普通缓冲区呢?

First make it work, then make it fast.

 

注意:对于普通缓冲区,Java底层会进行优化处理,效率也是很高的。

 

 

 

 

 

 

  • 大小: 9.9 KB
分享到:
评论

相关推荐

    xnio-nio-3.8.0.Final-API文档-中文版.zip

    赠送jar包:xnio-nio-3.8.0.Final.jar; 赠送原API文档:xnio-nio-3.8.0.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API...

    xnio-nio-3.8.0.Final-API文档-中英对照版.zip

    赠送jar包:xnio-nio-3.8.0.Final.jar; 赠送原API文档:xnio-nio-3.8.0.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API...

    xnio-nio-3.8.4.Final-API文档-中英对照版.zip

    赠送jar包:xnio-nio-3.8.4.Final.jar; 赠送原API文档:xnio-nio-3.8.4.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API...

    xnio-nio-3.8.4.Final-API文档-中文版.zip

    赠送jar包:xnio-nio-3.8.4.Final.jar; 赠送原API文档:xnio-nio-3.8.4.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API...

    Java IO, NIO and NIO.2 原版pdf by Friesen

    New I/O (NIO), and NIO.2 categories. You learn what each category offers in terms of its capabilities, and you also learn about concepts such as paths and Direct Memory Access. Chapters 2 through 5 ...

    Java IO, NIO and NIO.2(Apress,2015)

    Java I/O, NIO, and NIO.2 is a power-packed book that accelerates your mastery of Java's various I/O APIs. In this book, you'll learn about classic I/O APIs (File, RandomAccessFile, the stream classes ...

    httpcore-nio-4.3.jar包

    2. **Java NIO基础** Java NIO(New IO)是Java 1.4引入的一套新的I/O API,替代了传统的BIO(Blocking IO)。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。通道可以读写数据,缓冲区...

    Java IO, NIO and NIO.2

    Java IO、NIO以及NIO.2是Java中用于处理输入/输出操作的三种主要机制。本书《Java IO, NIO and NIO.2》旨在深入浅出地介绍这些机制,同时书中内容均为英文。接下来将详细介绍这些知识点。 **Java IO** Java IO是...

    Pro Java 7 NIO.2.pdf

    根据提供的文件信息,“Pro Java 7 NIO.2.pdf”由Anghel Leonard于2011年编写,主要介绍了Java 7中的新输入/输出(NIO)API,特别是NIO.2(JSR 203)所带来的增强功能。这本书通过一系列章节详细讲解了如何使用NIO.2...

    Java I/O, NIO and NIO.2

    Java I/O, NIO, 和 NIO.2 是Java平台中处理输入/输出操作的核心组件,对于任何Java开发者来说,理解和掌握这些概念至关重要。本文将深入探讨这些技术,旨在提供一个全面而详尽的概述。 Java I/O(Input/Output)是...

    Apress.Pro.Java.7.NIO.2.2011

    《Apress.Pro.Java.7.NIO.2.2011》这本书专注于讲解Java 7中的非阻塞I/O(Non-blocking I/O, NIO)和NIO 2的高级特性,是Java开发者深入理解这一关键领域的重要参考资料。NIO在Java平台中扮演着至关重要的角色,特别...

    JDK1.7 之java.nio.file.Files 读取文件仅需一行代码实现

    JDK1.7 之 java.nio.file.Files 读取文件仅需一行代码实现 java.nio.file.Files 类是 JDK1.7 中引入的新的文件操作类,该类包含了许多有用的方法来操作文件。其中,Files.readAllBytes(Path) 方法可以将整个文件...

    NIO项目源码.zip

    - `java.nio.channels.SelectionKey`:每个已注册的通道都会有一个对应的SelectionKey,它包含了通道与选择器之间的关系以及感兴趣的事件类型。 3. NIO工作流程 - 打开通道:例如创建一个FileChannel或...

    基于Java NIO实现五子棋游戏.zip

    基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...

    java NIO.zip

    2. **缓冲区(Buffers)**: 缓冲区是NIO中用于存储数据的容器,它们是固定大小的,并且具有特定类型的。Java NIO提供了诸如ByteBuffer、CharBuffer、IntBuffer等类型,对应于不同的数据类型。缓冲区具有读写位置,...

    Java.nio 与Java.io比较

    2. **缓冲区管理**:Java.nio使用缓冲区来存储数据,这比直接操作流更加高效,因为数据可以预先加载到缓冲区中,然后进行批量处理。 3. **文件映射缓冲区**:对于大文件的处理,Java.nio提供了一个名为`...

    httpcore-nio-4.4.13.jar

    java运行依赖jar包

Global site tag (gtag.js) - Google Analytics