Java NiO Study Notes (1) knowledge about buffer and channel

Source: Internet
Author: User

I. Basic Concepts

Io is the process of copying data from the primary storage and external devices (hard disks, terminals, and networks. Io is the underlying function implementation of the operating system, which is completed by I/O commands.

The system provides advanced tools for executing I/O in all languages. In Java programming, standard lower version I/O uses a stream to complete I/O operations. All I/O operations are considered as a single byte flow, an object called Stream moves one byte at a time.

NIO is a new IO that emerged after jdk1.4. The officially advertised NiO by Sun has the following features:

-Provides buffer cache support for all original types;
-Character set encoding solution (charset );
-Channel: A new original I/O abstraction;
-Supports file access interfaces for lock and memory ing files;
-Provides non-bloking (non-bloking) non-blocking high-scalability network I/O.

The NiO package (Java. NiO. *) introduces four key abstract data types that work together to solve some problems in traditional I/O classes.
1. Buffer: it is a linear table structure that contains data and is used for reading and writing. A special class is also provided for I/O operations on memory ing files.
2. charset: it provides Unicode string projection to byte sequence and Inverse Projection Operations.
3. channels: contains three channels: socket, file, and pipe. It is actually a two-way communication channel.
4. selector: It combines multiple asynchronous I/O operations into one or more threads.

Ii. Buffer & channel (buffer and channel)

The buffer and channel are the core objects in NIO, and the channel is the simulation of the original IO stream. All data must be transmitted through the channel. The buffer is essentially a container object, all objects sent to the channel must first be placed in a buffer zone.

1. What is a bufer? Class graph structure? In JDK, how does one implement it? Method introduction?

(1)What is buffer??

A bufer is an object that contains the data to be written or read. This is an important difference between NiO and IO. In Stream-oriented I/O, you can directly write data or directly read data to stream. In the NIO database, all data is processed using a buffer. When reading data, it is directly read into the buffer. When writing data, it is written to the buffer. When you access the data in NIO at any time, you put it in the buffer zone.

The buffer is essentially an array. It is usually a byte array, but other types of arrays can also be used. However, a buffer zone is not just an array. The buffer zone provides structured access to data, and supports tracking system read/write processes.

To put it simply, the buffer is a continuous memory block, which is the primary location for reading or writing NiO data.



(2)Structure of the buffer class diagram

From the class diagram, we can see that NiO supports buffer caching for all original data types. Besides the methods in bytebuffer, the methods in other classes are basically the same.

It can be seen that mappedbytebuffer is a direct subclass of bytebuffer. In the API, we can see such a sentence: A direct byte buffer whose content is a memory-mapped region of a file. File Memory ing is supported.

(3)How is buffer implemented in JDK??

You can see from the JDK source code that the buffer class is an abstract class with five attributes: Mark, position, limit, capacity, and address. In addition, you can see the following line of comment:

// Invariants: Mark <= position <= Limit <= capacity

A buffer is mainly controlled by three variables: Position, limit, and capacity. The meanings of these three variables are as follows:

Parameters

Write mode

Read mode

Position

Number of units of data currently written

Number of units of data currently read

Limit

The maximum number of data units that can be written. The default value is the same as capacity.

Indicates the maximum number of data units that can be read, which is consistent with the data volume previously written.

Capacity

Buffer Capacity

Buffer Capacity

The buffer abstract class does not specify the implementation method of the buffer. You can see its sub-classes. For example, there are several more attributes in bytebuffer, including the final byte [] type attribute, we can see that buffer is actually implemented using arrays.

 

(4)Some methods in buffer?

The most basic method for Attribute operations. In JDK, the set and get methods are not used. Check the source code to obtain the limit value of the current buffer using the public final int limit () method, set the limit value using the public final buffer limit (INT) method. Other attributes have corresponding methods.

Public final buffer flip (): used to convert the write mode to the Read mode.

Limit = position; // set limit to the position you just wrote.

Position = 0; // set the position to 0 and read from the beginning

Mark =-1;

Return this;

Public final buffer clear (): used to clear the buffer, prepare to be written again, set limit to capacity, and set position to 0.

Public final buffer rewind (): the source code is implemented as position = 0, mark =-1. The objective is to repeat the read.

Public final int remaining (): return limit-position;

Public final int hasremaining (): return limit> position;

 

Methods In the bytebuffer class, an important class inherited from the buffer:

First, we can see three more attributes in the bytebuffer class, one byte array type, one int type offset, and one Boolean Type isreadonly, both constructors are package-Private.

 

You can use the following method to generate a bytebuffer object:

Method 1:Bytebuffer bbuf = bytebuffer. Allocate (1024 );

View the source code to know that allocate executes the following sentence:

Return new heapbytebuffer (INT capacity, int capacity );

Heapbytebuffer is a subclass of bytebuffer and is executed in the heapbytebuffer constructor:

Super (-1, 0, Lim, Cap, new byte [Cap], 0 );

That is to say, the Constructed Method in bytebuffer is called and used within the package range. This method does the following work. First, call the buffer constructor to initialize mark, position, limit, and capacity, then initialize the bytebuffer attribute byte array, and then start offset, in this way, the allocate method can be used to construct a bytebuffer object.

 

Method 2:Bytebuffer bbuf = bytebuffer. Wrap (New byte [1024] array, 0, 1024 );

This method is useful when the byte array already exists, pass in the byte array directly, and then pass in the start value and end value. The default wrap implementation is that the initial value is passed into 0, and the end value is passed into the length array. Length of the byte array.

 

Other important methods in the bytebuffer class:

Get (byte [] DST) or get (byte [] DST, int offset, int Len)

(This method is used to obtain the data at the specified position in the current bytebuffer and assign it to DST, and finally return the current object itself. When the method is implemented, the first step is to check whether the parameter is valid. The checkbounds static package range private method is called. Check whether Len is greater than remaining, and then assign values to the DST array cyclically, and finally return the object .)

 

Put (byte [] SRC) or put (byte [] SRC, int offerset, int Len)

(This method is similar to the previous get method. The function is to put the existing byte array from 0 to the current bytebuffer, and finally return the bytebuffer itself .)

 

Put (bytebuffer SRC)

(This method puts SRC remaining into the current bytebuffer one by one, and finally returns the current bytebuffer .)

 

There are also typed get methods, such as getint (), getfloat (), and getshort.

 

(5)More buffer content?

Buffer shard: the slice () method creates a seed Buffer Based on the existing buffer, and the new buffer shares part of the data with the original buffer.

Read-Only Buffer: You can call the asreadonlybuffer () method of the buffer zone to convert any common buffer zone to a read-only buffer. This method returns a buffer with the same size as the original buffer zone (and shares data with it ), but it is read-only. Read-Only buffers are useful for protecting data. There is no way to change the read-only buffer to writable.

The following example partitions the buffer and operates the data:

// Generate a bytebuffer instance

Bytebuffer buffer = bytebuffer. Allocate (10 );

// Initialize the bytebuffer instance

For (INT I = 0; I <buffer. Capacity (); ++ I ){

Buffer. Put (byte) I );

}

// Modify the position (start point) and limit (End Point) of the buffer)

Buffer. Position (3 );

Buffer. Limit (7 );

// Shard the buffer.

Bytebuffer slice = buffer. Slice ();

// Perform operations on the sharded data

For (INT I = 0; I <slice. Capacity (); ++ I ){

Byte B = slice. Get (I );

B * = 11;

Slice. Put (I, B );

}

// Locate and output the result

Buffer. Position (0 );

Buffer. Limit (buffer. Capacity ());

While (buffer. Remaining ()> 0 ){

System. Out. println (buffer. Get ());

}

Direct or indirect Buffer: the direct buffer can speed up the I/O read and write, and use allocatedirect (INT capacity) to generate a direct buffer.

Memory ing file: the following code maps a filechannel (all or part of it) to the memory.

. Map the first 1024 bytes of the file to the memory:

Mappedbytebuffer MBB = FC. Map (filechannel. mapmode. read_write, 0, 1024 );

1. What is a channel? Class graph structure? In JDK, how does one implement it? Method introduction?

(1)What is a channel??

A channel is an object that can be used to read and write data. Compare NiO with the original I/O, and the channel is like a stream.

As mentioned above, all data is processed through the buffer object. You will never write bytes directly into the channel. Instead, you write data to a buffer that contains one or more bytes. Similarly, you will not directly read the byte from the channel, but read the data from the channel into the buffer zone and then get the byte from the buffer zone.

To put it simply, the channel is the source or destination of the data. It is used to provide data to the buffer or read the buffer data, and provides asynchronous support for I/O.



(2)Structure of the channel class diagram?

Java. NIO. channels. A channel is a public interface, which is implemented by all sub-channels. NIO. the channels package also provides good classes such as channels, filelock, selectionkey, selector, and pipe. It contains socket, file, and pipe pipelines, which are actually two-way communication channels.

(3)How is channel implemented in JDK??

Two methods are defined in the channel interface.

Public Boolean isopen (); // tells whether or not this channel is open

Public void close () throws ioexception (); // close this channel

Filechannel: Use the following three methods to obtain a filechannel instance:

Fileinputstream. getchannel ()

Fileoutputstream. getchannel ()

Randomaccessfile. getchannel ()

The channel mentioned above is the source or destination of the data, which is used to provide data to the bufer or read data from the buffer. Then there should be corresponding read and write methods in the subclass that implements this interface.

You can use the following methods in filechannel:

Public long read (bytebuffer [] dsts)

Reads a sequence of bytes from this channel into the given buffers.

Public long write (bytebuffer [] SRCS)

Writes a sequence of bytes to this channel from the given buffers.

Additional: file lock

Filechannel provides two methods to obtain filelock

Filelock lock ();

Filelock lock (long position, long size, Boolean size );

Example:

To obtain the lock on a part of a file, you must call the lock () method on an opened filechannel. Note: To obtain an exclusive lock, you must open the file in write mode.

Randomaccessfile RAF = new randomaccessfile ("filelocks.txt", "RW ");

Filechannel fc = Raf. getchannel ();

Filelock lock = FC. Lock (START, end, false );

After you have the lock, you can perform any necessary sensitive operations and then release the lock:

Lock. Release ();

Socketchannel: Use the following two methods to obtain an instance of socketchannel:

Socketchannel. open (); // open a socket Channel

Socketchannel. Open (socketaddress remote );

// Call the above method and connect (remote)

Sample Code:

Inetsocketaddress socketaddress = new inetsocketaddress ("www.baidu.com", 80 );

Socketchannel SC = socketchannel. Open (socketaddress );

SC. Read (buffer );

Buffer. Flip ();

Buffer. Clear ();

SC. Write (bufer );

Datagramchannel: it has the same or similar methods with other channels.

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.