Java Network Programming from entry to mastery (33): non-blocking I/O Buffer (Buffer)

Source: Internet
Author: User

If the data transmission in synchronous I/O mode is compared to the sporadic data transmission mode (here, sporadic data transmission is carried out in sporadic bytes ), data transmission in non-blocking I/O mode can be compared to the data transmission container mode (a buffer layer is added between the byte and the Low-layer data transmission. Therefore, the buffer zone can be seen as a container loaded with bytes ). As you can imagine, if we want to deliver a small amount of goods, it seems a little inefficient to use containers, and if we want to transport hundreds of tons of goods, the cost of using containers for transportation will be lower. The same is true during data transmission. If the data volume is small, it is more suitable to use the synchronous I/O mode. If the data volume is large (usually in the unit of G ), non-blocking I/O is more efficient. Therefore, theoretically, the larger the data volume, the lower the unit cost of using the non-blocking I/O method. The cause of this result is directly related to some features of the buffer. In this section, we will explain some of the main features of the buffer zone, so that readers can fully understand the concept of the buffer zone and improve the execution efficiency of the program through the buffer zone.

Create a buffer

Java provides seven basic buffers managed by seven classes, which can be found in the java. nio package. The seven classes are as follows:

ByteBuffer
Protocol Buffer
IntBuffer
CharBuffer
FloatBuffer
DoubleBuffer
LongBuffer
The methods in these seven classes are similar, but their return values or parameters correspond to the corresponding simple type. For example, the get method of the ByteBuffer class returns the data of the byte type, the put method requires a byte parameter. The data types returned and passed by the get and put methods in the CharBuffer class are char. None of these seven classes have public constructor methods. Therefore, they cannot use new to create corresponding object instances. These classes can be used to create corresponding object instances in two ways.

1. Create a buffer using the static allocate method.

These seven classes all have a static allocate method, which allows you to create a buffer object with the maximum capacity limit. Allocate is defined as follows:

The allocate method in the ByteBuffer class:

Public static ByteBuffer allocate (int capacity)

The allocate method in the IntBuffer class:

Public static IntBuffer allocate (int capacity)

The allocate method definition in the other five buffer classes is similar to the above definition, but the type of the returned value is the corresponding buffer class.

The allocate method has the capacity parameter used to specify the maximum buffer capacity. Capacity cannot be less than 0; otherwise, an IllegalArgumentException exception is thrown. Allocate is used to create a buffer. Instead of allocating the buffer capacity to the buffer, it dynamically allocates the buffer size based on the data stored in the buffer. (In fact, in the lower-layer Java, the heap in the data structure is used to manage the buffer size. Therefore, this capacity can be a large value, such as 1024*1024 (1 M ). Use allocate as follows:

ByteBuffer byteBuffer = ByteBuffer. allocate (1024 );
IntBuffer intBuffer = IntBuffer. allocate (1024 );

When using allocate to create a buffer, note that capacity is different with the buffer. For example, when creating a byte buffer, capacity indicates the number of bytes. When creating an integer (int) buffer, capacity refers to the number of int-type values. If converted to words, the capacity value should be multiplied by 4. For example, the maximum number of bytes that the intBuffer buffer can accommodate in the code above is 1024*4 = 4096.

2. Create a buffer using the static wrap method.

You can use the allocate method to create an empty buffer. However, the wrap method can use existing data to create a buffer. The wrap method can directly convert an array to a buffer of the corresponding type. The wrap method has two overload forms, which are defined as follows:

The wrap method in the ByteBuffer class:

Public static ByteBuffer wrap (byte [] array)
Public static ByteBuffer wrap (byte [] array, int offset, int length)

The wrap method in the IntBuffer class:

Public static IntBuffer wrap (byte [] array)
Public static IntBuffer wrap (byte [] array, int offset, int length)

The wrap method definition in the other five buffer classes is similar to the preceding definition, but the type of the returned value is the corresponding buffer class.

The array parameter in the wrap method is the array to be converted (if it is another buffer class, the array type is the corresponding simple type, for example, the array of the wrap method in the IntBuffer class is of the int [] type ). Offset is the offset of the sub-array to be converted, that is, the start index of the sub-array in the array. Length is the length of the sub-array to be converted. The last two parameters can be used to convert part of the array into a buffer object. They are used as follows:

Byte [] myByte = new byte [] {1, 2, 3 };
Int [] myInt = new int [] {1, 2, 3, 4 };
ByteBuffer byteBuffer = ByteBuffer. wrap (myByte );
IntBuffer intBuffer = IntBuffer. wrap (myInt, 1, 2 );
You can use the buffer class capacity method to obtain the buffer size. The capacity method is defined as follows:

Public final int capacity ()
If you use the allocate method to create a buffer, the return value of the capacity method is the value of the capacity parameter. However, when using the wrap method to create a buffer, the return value of the capacity method is the length of the array. Note that when using the wrap method to convert the word group of the array, the capacity length is still the length of the original array. For example, the capacity value of the intBuffer buffer in the code above is 4 rather than 2.

In addition to converting an array into a buffer, you can also use the array method of the buffer class to convert the buffer into an array of the corresponding type. The method for defining the array method of the IntBuffer class is as follows (the definition of the array of other buffer classes is similar ):

Public final int [] array ()
The following code demonstrates how to use the array method to convert a buffer to an array of the corresponding type.


Int [] myInt = new int [] {1, 2, 3, 4, 5, 6 };
IntBuffer intBuffer = IntBuffer. wrap (myInt, 1, 3 );
For (int v: intBuffer. array ())
System. out. print (v + "");
After executing the code above, we found that the output result is 1 2 3 4 5 6, not 2 3 4. This indicates that the entire array is actually converted into a buffer during the process of converting the sub-array into a buffer. This is after packaging the sub-array with wrap, the capacity value is still the true cause of the original array length. When using the array method, note that the array method cannot be used in the following two buffers:

Read-Only Buffer
If the array method of the read-only buffer is used, a ReadOnlyBufferException is thrown.

The buffer created using the allocateDirect method.
If you call the array method in this buffer, an UnsupportedOperationException will be thrown.

The hasArray method of the buffer class can be used to determine whether the buffer can use the array method. If true is returned, the buffer can use the array method. Otherwise, using the array method will throw one of the above two exceptions.

Note: The array returned using the array method is not a copy of the buffer data. The returned array is actually the data in the buffer, that is, the array method only returns the reference of the buffer data. When the data in the array is modified, the data in the buffer is also modified. This topic will be detailed in the next section "Read and Write Data in the buffer zone.


Among the preceding seven buffer classes, the ByteBuffer class and the CharBuffer class have another method to create a buffer object.

L ByteBuffer class

You can use the allocateDirect method of the ByteBuffer class to create a ByteBuffer object. The allocateDirect method is defined as follows:

Public static ByteBuffer allocateDirect (int capacity)


The allocateDirect method can be used to allocate consecutive bytes of capacity size at a time. Although the allocateDirect method can be used to create ByteBuffer objects with continuous space, this method is not platform independent. That is to say, using allocateDirect to create ByteBuffer objects on some operating system platforms will greatly improve the efficiency, while on other operating system platforms, the performance will be very poor. In addition, the allocateDirect method takes a long time to allocate memory space, which is also slow when space is released. Therefore, exercise caution when using the allocateDirect method.

The isDirect method can be used to determine the buffer objects (other buffer classes also have the isDirect method, because ByteBuffer objects can be converted to other buffer objects, which will be explained later) which method is used to create the buffer? If the isDirect method returns true, the buffer object is created using the allocateDirect method. Otherwise, the buffer object is created using other methods.

L CharBuffer class

We can find that there is no string buffer in the above seven buffers, and the string is the most common data type in the program. But don't worry. Although the java. nio package does not provide a string buffer, it can convert the string into a character buffer (the CharBuffer object ). In the CharBuffer class, the wrap method has two additional reload Methods besides the preceding two reload methods. Their definitions are as follows:

Public static CharBuffer wrap (CharSequence csq)
Public static CharBuffer wrap (CharSequence csq, int start, int end)

The csq parameter indicates the String to be converted, but we note that the csq type is CharSequence rather than String. The CharSequence class Java contains four parent classes that can represent strings. These four classes are String, StringBuffer, StringBuilder, and CharBuffer, stringBuffer does not have any relationship with the buffer class mentioned in this section. This class is available in java. in the lang Package ). That is to say, the wrap method of the CharBuffer class can convert the objects of these four classes into CharBuffer objects.

The start and end parameters are the start index of the substring and the next position of the end index, respectively. For example, the statement to convert "23" in string "1234" to CharBuffer object is as follows:

CharBuffer cb = CharBuffer. wrap ("1234", 1, 3 );


The following code demonstrates how to use the wrap method to convert different forms of strings into CharBuffer objects.

StringBuffer stringBuffer = new StringBuffer ("Creating a CharBuffer object through StringBuffer ");
StringBuilder stringBuilder = new StringBuilder (

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.