One of the most central concepts in Java.io is Stream, stream-oriented programming. In Java, a stream is either an input stream or an output stream; it cannot be both. Java.nio has three core concepts: Selector, Channel, and Buffer. In Java.nio, we program for blocks or buffers. A Buffer is itself a block of memory, but the underlying implementation is actually an array. Buffers are used to read and write data. In addition to arrays, buffers provide structured access to data and can be traced to system reads and writes.
The 7 native data types in Java all have corresponding Buffer types, such as IntBuffer, LongBuffer, ByteBuffer and CharBuffer, but there is no BooleanBuffer type. A Channel is an object to which data can be written or read, similar to a Stream in java.io.
All data is written to or read from a Buffer, and is never written to or read from a Channel.
Unlike a Stream, a Channel is bidirectional. A Stream can only be an InputStream or an OutputStream. A Channel can read, write, or read from a Stream.
Because a Channel is bidirectional, it can better reflect the actual situation of the underlying operating system. In Linux, the Channel of the underlying operating system is bidirectional.
The meanings of three important state attributes in NIO Buffer: position, limit, and Capacity. Let’s start with a small sample code:
public class NioTest1 { public static void main(String[] args) { IntBuffer buffer = IntBuffer.allocate(10); for (int i = 0; i < 10; i++) { int random = new SecureRandom().nextInt(20); buffer.put(random); //put write data to buffer} // read/write convert buffer.flip(); while (buffer.hasRemaining()) { System.out.println(buffer.get()); //get reads data from buffer}}}Copy the code
Ron Hitchens wrote a book on Java NIO that introduced niO-related concepts very clearly. Here is an introduction to Buffer:
- Capacity
The maximum number of data elements a buffer can hold. This capacity is set when the buffer is created and can never be changed.
- Upper bound (Limit)
The first element of the buffer that cannot be read or written. In other words, the count of existing elements in the buffer.
- Position
The index of the next element to be read or written. The position is automatically updated by the corresponding get() and PUT () functions.
- Mark
A memo location. Call mark() to set mark = postion. Call reset() to set position = mark. The tag is undefined before setting (undefined). The relationship between these four attributes always follows: 0 <= mark <= position <= limit <= capacity Changes in position, limit, and capacity during API calls:
One final little example:
public class NioTest4 { public static void main(String[] args) throws Exception { FileInputStream inputStream = new FileInputStream("input.txt"); FileOutputStream outputStream = new FileOutputStream("output.txt"); FileChannel inputChannel = inputStream.getChannel(); FileChannel outputChannel = outputStream.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(512); while (true) { buffer.clear(); // What happens if you comment out the line? Buffer.clear () is commented out, and the position of the buffer is equal to limit after the last sentence of the while loop outputChannel.write, so that read returns 0. Flip causes the contents of a buffer to be repeatedly written to int read = inputChannel.read(buffer); System.out.println(read); if (read == -1) { break; } buffer.flip(); outputChannel.write(buffer); } inputChannel.close(); outputChannel.close(); }}Copy the code