Java NIO in the Channel Interface

 

Channel channel, can be part or all of the specified file is mapped directly to Buffer.

 

Can not directly read and write data in the Channel, Channel can only interact with the ByteBuffer.

When reading data, the map data in a ByteBuffer Channel data usage removed.

When writing data, the data into the Buffer, the data is then written to Channel ByteBuffer in.

 

Channel Interface is a commonly used implementation class are:

  • FileChannel for reading and writing files
  • Channel UDP communications for DatagramChannel
  • ServerSocketChannel, SocketChannel Channel TCP for communication

 Here only FileChannel, for UDP, Channel TCP communication is re-introduced at the time of writing network programming.

 

 

Channel common methods:

  • Byte stream objects .getChannel () // Get Channel object of corresponding type. Only the byte stream objects have the getChannel () method.
  • Channel object .read (ByteBuffer buffer) // read from the input stream corresponding to Channel data into buffer, only ByteBuffer buffer type, not other types Buffer
  • Channel object .write (ByteBuffer buffer) // data buffer to the channel corresponding to the stream
  • Channel object .position () // will return Channel recorded position of the pointer, the return value is long type
  • Channel object .position (long index) // Channel record pointer is adjusted to a specified location
  • Channel object .map (mapping mode, the start index, length) of the part of the file // / MappedByteBuffer all mapped to one object, the object returns the MappedByteBuffer.

 

 

 Example: reading documents, once read

1          // Create a Channel 
2          File File = new new ( "./ 1.txt" File );
 3          FileInputStream in = new new FileInputStream (File);
 4          FileChannel Channel = in.getChannel ();   // get the input stream object file by Channel
 . 5  
. 6          // Create Buffer 
. 7          the ByteBuffer ByteBuffer = ByteBuffer.allocate (1024 );
 . 8  
. 9          // read the data into the Buffer Channel. Channel can only interact with the ByteBuffer, can not interact with other Buffer 
10          channel.read (ByteBuffer);
 11  
12          // call the ByteBuffer flip () method to adjust the pointer, make use of the data preparation 
13         ByteBuffer.flip ();
 14  
15          // for decoding ByteBuffer converted to CharBuffer. Because ByteBuffer can not be directly converted to String, () is not a String converted file contents through toString. ByteBuffer should be converted to CharBuffer. 
16          Charset charset = Charset.forName ( "GBK");     // create Charset object. Windows creates a text file with the default GBK coding, which is the default coded character set is GBK.
17          // Here coded character set used for encoding a character set corresponding to the file. If we specified when creating a file character set is UTF-8, UTF-8 or modified to encode the files in Explorer, then here using UTF-8. 
18          CharsetDecoder Decoder = charset.newDecoder ();    // create a decoder 
19          CharBuffer CharBuffer = decoder.decode (ByteBuffer);    // use the decoder to decode the ByteBuffer, get CharBuffer
 20  
21          // here CharBuffer not call flip (), but no data call
22 is  
23 is          // () can be obtained by get char, may be read into a char [] by get (char [] arr), or using toString () is converted into String 
24          System.out.println (charBuffer.get ( ));   // get the first character 
25          System.out.println (charBuffer.toString ());   // the remaining portion is converted into String CharBuffer output. Note that the remaining portion of the data.
26          
27          // When sout output of an object, the object will automatically call the toString () method to convert the object to a String output.
28          // so it can be written as System.out.println (CharBuffer); 
29          
30          byteBuffer.clear ();
 31 is          charBuffer.clear ();
 32          channel.close ();
 33 is          in.close ();

 

 

 

Example: Read the file, read cycle

1          // Create Channel 
2          the FileInputStream in = new new the FileInputStream ( "./ 1.txt" );
 . 3          FileChannel Channel = in.getChannel ();
 . 4  
. 5          // Create Buffer 
. 6          the ByteBuffer ByteBuffer = ByteBuffer.allocate (102 );
 . 7          CharBuffer CharBuffer;
 . 8  
. 9          // Create a decoder 
10          of a CharsetDecoder Charset.forName = decoder ( "GBK" ) .newDecoder ();
 . 11  
12 is          // loop reads data 
13 is          the while (! channel.read (ByteBuffer) = -. 1) {   / /after the read (), Channel pointer is automatically moved back. -1 data not readable. 
14              ByteBuffer.flip ();    // do the data used to prepare 
15              CharBuffer = decoder.decode (ByteBuffer);    // decoder 
16              System.out.println (CharBuffer);
 . 17              byteBuffer.clear ();    // empty, ready for the next use only. You must be emptied byteBuffer. 
18              / * 
19              since mechanisms channel.read (byteBuffer) is to read data channel to ByteBuffer, returns content length of ByteBuffer, instead of returning the data read from the length of the channel.
20 is              if ByteBuffer not empty, after the first cycle, the pointer points to the end of the recording ByteBuffer, execution channel.read (byteBuffer) again, as ByteBuffer is full, there is no remaining space,
 21             Channel does not read the new data, and returns the content length is not equal to -1 byteBuffer cycle (data byteBuffer uses the first) will be executed again.
22              would have been using for the first time to read the data into an infinite loop.
23 is              * / 
24              charBuffer.clear ();    // this can be a default, because the value of the next time are automatically covered. 
25          }
 26 is  
27          channel.close ();
 28          in.close ();

 

 

 

Example: write file

1          // Create Channel 
2          a FileOutputStream OUT = new new a FileOutputStream ( "./ 2.txt" );
 . 3          FileChannel Channel = out.getChannel ();
 . 4  
. 5          // Create Buffer 
. 6          the ByteBuffer Buffer = ByteBuffer.allocate (1024 );
 . 7  
. 8          // data to be written into the Buffer 
. 9          buffer.put ( "Hello World!" .getBytes ());
 10  
. 11          @ to adjust the pointer, indicating the available data. Otherwise, the available data is empty Buffer 
12 is          buffer.flip ();
 13 is  
14          // The data is written to Buffer Channel. Synchronized written to the file. 
15         channel.write(buffer);
16 
17         buffer.clear();
18         channel.close();
19         out.close();

 

The above three examples, the use Buffer, and the nature of the conventional buffer IO streams is the same, write speed is very fast, but did not use the channel mapping.

 

 

 

Example: Mapping channel read-write file

. 1 File inFile = new new ( "./ 1.txt" File );
 2          FileChannel inChannel = new new the FileInputStream (inFile) .getChannel ();
 . 3          FileChannel outChannel = new new a FileOutputStream ( "./ 2.txt" ) .getChannel ();
 . 4  
. 5          / * 
. 6          the documents Channel input stream is mapped to the Buffer, Channel mapping input stream can be read-only.
7          mapping the entire file. The inFile as a separate object is to obtain the file length
 . 8          * / 
. 9          a MappedByteBuffer inChannel.map Buffer = (FileChannel.MapMode.READ_ONLY, 0 , inFile.length ());
 10  
. 11          // contents written to the Output Buffer of Channel stream, synchronized written to the output file. This enables files to copy. 
12         outChannel.write(buffer);
13 
14         inChannel.close();
15         outChannel.close();

 

 

 

Example: Channel mapping file read

1  // Create Channel 
2          File inFile = new new ( "./ 1.txt" File );
 . 3          FileChannel inChannel = new new the FileInputStream (inFile) .getChannel ();
 . 4  
. 5          // mapped into the Buffer 
. 6          a MappedByteBuffer Buffer = inChannel.map (FileChannel.MapMode.READ_ONLY, 0 , inFile.length ());
 . 7  
. 8          // create a decoder. MappedByteBuffer is a subclass of ByteBuffer, to be converted to CharBuffer use. 
. 9          of a CharsetDecoder Charset.forName = Decoder ( "GBK" ) .newDecoder ();
 10          
. 11          // channel mapping MappedByteBuffer obtained, not necessarily Flip () before the data is a pointer adjustment in MappedByteBuffer, a pointer has been adjusted.
12         // course buffer.flip (); also written on the line
 13 is          
14          // convert CharBuffer 
15          CharBuffer CharBuffer = decoder.decode (Buffer);
 16  
. 17          // data used in CharBuffer 
18 is          System.out.println (CharBuffer);
 . 19  
20 is          buffer.clear ();
 21 is          charBuffer.clear ();
 22 is          inChannel.close ();

 

Use the channel map is the fastest. However, if a large file mapping, such as 1,2 G, disposable map the entire file will take up a lot of memory, it will lead to performance degradation, it can now be read sequentially mapped using a loop.

Only buffer may be used, without using the channel mapping sequentially read by the circulation, but the speed will be slower.

 

If you do not have the data (content) into a String, you do not have to use the decoder.

 

 

 

RandomAccessFile Channel Mapping class may also be used:

1       // Create a Channel 
2          File File = new new File ( "./ 1.txt" );
 3          RandomAccessFile RandomAccessFile = new new RandomAccessFile (File, "rw");   // use RandomAccessFile can specify the file open with 
4          FileChannel Channel = RandomAccessFile. the getChannel ();
 . 5  
. 6          / * 
. 7          to Channel is mapped to the Buffer.
8          read only opened to r, only map is read-only; in rw to opened, regardless of the mapping mode designated read-only or read-write, read and write are mapped.
9          After That is, in a file opened rw performs channel mapping, Channel may be read, and can write (to the file sync)
 10           * / 
11         Buffer = channel.map a MappedByteBuffer (FileChannel.MapMode.READ_WRITE, 0 , file.length ());
 12 is  
13 is          channel.position (file.length ()); // record the pointer to the end of Channel 
14          channel.write (Buffer );    // the end of the write buffer Channel, i.e., copy the contents appended to the end 
15  
16          channel.close ();
 . 17          randomAccessFile.close ();

 

Using the advantage RandomAccessFile channel mapping class:

You can specify the file to open the way to open the write mapping, Channel can either read, but also write for files to be read at the same time.

 

 

 

note:

Before using the data in the ByteBuffer, first Flip () adjust the position of the pointer.

Even if the subsequent use ByteBuffer, first call clear () to clear the ByteBuffer before use (at the time of data reading cycle, often to use).

 

File not closed, but the File To close the corresponding flow.

RandomAccessFile, Channel and flow is very similar, and both need to be closed.

Buffer is only a container, not a stream, without shutting down.

 

Guess you like

Origin www.cnblogs.com/chy18883701161/p/10928979.html