- Channel
- Channel Basics
- Channel Open
- Channel usage
- Channel off
- Scatter/gather
- File Channel
- File Channel code example
- Socket Channel
- Socket Channel code example
- Summarize
Channel
The channel is used to transfer data efficiently between the byte buffer and the entity on the other side of the channel, usually a file or socket.
Channel, in this way, you can use the minimum total overhead to access the IO service of the operating system itself, the buffer is a breakpoint inside the channel for sending and receiving data.
Channel Basics
Top-level interface channel, secondary interface Writablebytechannel, Readablebytechannel, Interruptiblechannel and so on. The interface describing the behavior of the channel is defined in the Java.nio.channels package, and the specific channel implementations are derived from the classes in the Java.nio.channels.spi.
Channel Open
IO can be divided into two broad categories: File IO and stream io, corresponding to the file channel and socket channel. Embodied in the FileChannel class and three socket channel classes: Socketchannel, Serversocketchannel, and Datagramchannel.
The code is as follows:
//Open SocketchannelSocketchannel sc = Socketchannel.Open( ); Sc.Connect(NewInetsocketaddress ("Somehost", port));//Open ServersocketchannelServersocketchannel SSC = Serversocketchannel.Open( ); SSc.Socket( ).Bind(NewInetsocketaddress (port)); Datagramchannel DC = Datagramchannel.Open( );//filechannel can only be obtained by calling the Getchannel () method on Randomaccessfile, FileInputStream, or FileOutputStream objectsRandomaccessfile RAF =NewRandomaccessfile ("Somefile","R"); FileChannel FC = RAF.Getchannel( );
Channel usage
Use the channel to receive input from the console and print the received input in the console. The code is as follows:
Public Static void Main(string[] args)throwsIOException {//One read channel, one write channelReadablebytechannel Source = Channels.Newchannel(System.inch); Writablebytechannel dest = Channels.Newchannel(System. out);channelcopy(source,dest); Source.Close(); Dest.Close(); }Private Static void channelcopy(Readablebytechannel source, Writablebytechannel dest)throwsioexception{Bytebuffer bytebuffer = Bytebuffer.Allocate( -*1024x768); Bytebuffer flag = Bytebuffer.Allocate(4); while(source.Read(bytebuffer)! =-1) {Bytebuffer.Flip();//Output markerFlag.put((byte)‘-‘).put((byte)‘-‘).put((byte)‘-‘).put((byte) ' > '); Flag.Flip(); Dest.Write(flag); Dest.Write(Bytebuffer); Flag.Clear(); Bytebuffer.Compact(); } bytebuffer.Flip();//Make sure the buffer is clean while(Bytebuffer.hasremaining()) {flag.Putchar(‘-‘).Putchar(‘-‘).Putchar(‘-‘); Flag.Flip(); Dest.Write(Bytebuffer); Flag.Clear(); } }
The test input and output is as follows:
Channel off
Unlike buffers, channels cannot be reused, and opening a channel represents a specific link to a specific IO service and encapsulates the status of that link, when the channel is closed, the connection is lost, and the channel is not connected to anything.
When the Close method is called, it may cause the thread to block temporarily, and calling the Close method on the closed channel will not produce any action and will only return immediately. The channel state can be judged by the IsOpen method.
If a thread is interrupted, the channel that the thread accesses will be closed immediately, which is also a tradeoff for the robustness of the program.
Scatter/gather
Implement a simple IO operation in multiple buffers:
For write, the data is extracted sequentially from several buffers (gather) and sent along the channel. The gather process, like the full buffer content, is connected and stored in a large buffer before it is sent.
For read, data read from the channel is distributed sequentially (scatter) to multiple buffers, filling each buffer until the space of the data or buffer in the channel is exhausted.
The interface is defined as follows, where read and write enter the parameter buffer array:
Public InterfaceScatteringbytechannelextendsreadablebytechannel{ Public Long Read(Bytebuffer [] dsts)throwsIOException; Public Long Read(Bytebuffer [] DSTs,intOffsetintLengththrowsIOException;} Public InterfaceGatheringbytechannelextendswritablebytechannel{ Public Long Write(bytebuffer[] SRCs)throwsIOException; Public Long Write(bytebuffer[] SRCs,intOffsetintLengththrowsIOException;}
File Channel
Specifically FileChannel, the interface is as follows:
publicabstractclass FileChannel extends AbstractInterruptibleChannel implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
The FileChannel object is thread-safe (thread-safe).
The most powerful thing about file IO is asynchronous IO, which allows a process to request one or more IO operations from the operating system without having to wait for these operations to complete.
File Channel code example
- Writes buffer data to a file via a file channel
Public Static void Write(String FilePath)throwsException {/ * Write the file, use Fileoutputstream,randomaccessfile can. *//* Randomaccessfile file = new Randomaccessfile (FilePath, "RW"); */FileOutputStream file =NewFileOutputStream (NewFile (FilePath)); Bytebuffer Bytebuffer = Bytebuffer.Allocate( -); String str ="Hello LK";/ * Data Write buffer * /Bytebuffer.put(str.getBytes()); Bytebuffer.Flip(); FileChannel FileChannel = file.Getchannel();//write buffer data to file channelFileChannel.Write(Bytebuffer); Bytebuffer.Clear(); FileChannel.Close(); }
- Read the data in the file into the buffer via the file channel
Public Static void Read(String FilePath)throwsException {FileInputStream FileInputStream =NewFileInputStream (NewFile (FilePath));/ * A FileChannel object can only be passedCall the Getchannel () method on an open randomaccessfile, FileInputStream, or FileOutputStream object to get it,developers cannot directly create a filechannel*/FileChannel FileChannel = FileInputStream.Getchannel(); Bytebuffer Bytebuffer = Bytebuffer.Allocate( -);//Read the file channel into the bufferFileChannel.Read(Bytebuffer); Bytebuffer.Flip(); while(Bytebuffer.hasremaining()) {System. out.Print((Char) Bytebuffer.Get()); } bytebuffer.Clear(); FileChannel.Close(); }
Socket Channel
The new socket channel class is available 运行非阻塞模式,并且是可选择的
. With the new NiO class, one or several threads can manage hundreds of active socket connections, with little performance trending.
All socket channel classes (Datagramchannel, Socketchannel, and Serversocketchannel) are derived from the JAVA.NIO.CHANNELS.SPI package AbstractSelectableChannel
.
Datagramchannel and Socketchannel implement interfaces that define read and write functions and Serversocketchannel do not implement them. Serversocketchannel is responsible for listening for incoming connections and creating new Socketchannel objects, which in itself never transfer data.
Socket Channel code example
Start a serversocketchannel, listen for 8001 ports, non-blocking mode. Initiates 10 Socketchannel threads writing data to Serversocketchannel.
The Serversocketchannel code is as follows:
Serversocketchannel Serversocketchannel = Serversocketchannel.Open();/ * Non-blocking * /Serversocketchannel.configureblocking(false); Serversocketchannel.Bind(NewInetsocketaddress (port)); System. out.println("Serversocketchannel is ok,waiting @["+ LocalDateTime. Now() +"]"); for(; ; ) {Socketchannel Socketchannel = Serversocketchannel.Accept();if(Socketchannel = =NULL) {Thread.Sleep( +); System. out.println("Serversocketchannel sleep 1000ms.");Continue; } String Connectip = Socketchannel.Socket().getremotesocketaddress().toString(); System. out.println("Client has data coming, client IP is:"+ Connectip +", Time for"+ LocalDateTime. Now()); Bytebuffer Bytebuffer = Bytebuffer.Allocate(1024x768); Socketchannel.Read(Bytebuffer); Bytebuffer.Flip(); while(Bytebuffer.hasremaining()) {System. out.Print((Char) Bytebuffer.Get()); } socketchannel.Close(); } }
Start the 10 Socketchannel code as follows:
Private Static Final intPort =8001; Public Static void Main(string[] args) { for(intI=0;i<Ten; i++) {New Socketchannelimpl(Port,i).Start(); } }Private Static classSocketchannelimplextendsThread {Private intCount =0;Private intPort Public Socketchannelimpl(intPortintCount) { This.Port= port; This.Count= Count; }@Override Public void Run() {Try{Socketchannel Socketchannel = Socketchannel.Open();/ * Non-blocking * /Socketchannel.configureblocking(false); Socketchannel.Connect(NewInetsocketaddress (port)); for(;! Socketchannel.Finishconnect();) {System. out.println("Connectting ..."); Thread.Sleep( -); } bytebuffer Bytebuffer = Bytebuffer.Allocate(1024x768); String content ="Hello, I am client--------->"+ count; Bytebuffer.put(content.getBytes()); Bytebuffer.Flip(); Socketchannel.Write(Bytebuffer); Bytebuffer.Clear(); Socketchannel.Close(); }Catch(Exception e) {e.Printstacktrace(); } } }
The results of the operation are as follows:
Add:
Serversocketchannel Listening is 8001 port, you can in the browser, input: Http://localhost:8001/helloworld, you will find your Serversocketchannel can also receive data, This is also the basis for Web server processing.
Summarize
Above, understand the basic channel operation, file channel and socket channel Use example, I feel like a bit, not too much =. =
All of the above code examples can fork here: GitHub
Thanks
The above from the operation Director of the day group: Kun Less
Java NIO Channel