FileChannel
FileChannel是一个文件的通道,可以通过它来读写文件。FileChannel无法设置为非阻塞模式。
读数据:
1 2 3 4
| RandomAccessFile accessFile = new RandomAccessFile(filePath, "rw"); FileChannel fileChannel = accessFile.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buffer);
|
读数据时,使用read方法返回读取的数据大小,如果返回-1,就说明已经到了文件的最后。
写数据:
1 2 3 4 5 6 7 8
| String text = "..."; ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(text.getBytes()); buf.flip(); while(buf.hasRemaining()) { fileChannel.write(buf); }
|
write方法在写入数据时,每次写入的量是不定的,所以需要在循环体中把所有的数据写入文件。
使用完FileChannel之后,需要把通道关闭。
其他方法
position(long pos)
:该方法可以获取通道的当前位置,同时也可以设置在特定的位置进行读写操作。
1 2
| long pos = channel.position(); channel.position(pos +10);
|
这样操作会是数据之间存在空数据。
size
:size()方法将返回该通道里数据的大小。
truncate()
:该方法可以截取指定的数据长度,这样就可以达到截取文件的目的。
force()
:该方法将通道里尚未写入磁盘的数据强制写到磁盘上。
SocketChannel
SocketChannel是一个连接到TCP网络套接字的通道,一般会使用两个地方使用到它:使用SocketChannel连接到互联网上的某台服务器,或者使用ServerSocketChannel时,当有新的连接时,会自动创建SocketChannel。
读写数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress(ip, 80));
//读取数据 ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
//写入数据 ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(text.getBytes()); buf.flip(); while(buf.hasRemaining()) { channel.write(buf); } socketChannel.close();
|
非阻塞模式
当设置成非阻塞模式后,就可以在异步模式下调用connect(),read() 和write()了。
1 2 3 4 5 6 7
| socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(ip, 80)); while(! socketChannel.finishConnect() ){ ... }
socketChannel.close();
|
ServerSocketChannel
ServerSocketChannel 是一个可以监听新进来的TCP连接的通道,主要用于在服务器中监听连接。
1 2 3 4 5 6 7 8 9 10
| ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //打来通道 serverSocketChannel.socket().bind(new InetSocketAddress(90)); //绑定端口 while(true){ SocketChannel socketChannel = //获取连接 serverSocketChannel.accept(); ... }
... serverSocketChannel.close(); //关闭
|
非阻塞模式
ServerSocketChannel同样可以设置为非阻塞模式。此时,accept() 方法会立刻返回,如果还没有新进来的连接,返回的将是null。
1 2 3 4 5 6 7 8 9 10 11 12
| ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //打来通道 serverSocketChannel.socket().bind(new InetSocketAddress(90)); //绑定端口 while(true){ SocketChannel socketChannel = //获取连接 serverSocketChannel.accept(); if(socketChannel!=null){ ... } }
... serverSocketChannel.close(); //关闭
|
DatagramChannel
DatagramChannel是收发UDP包的通道,因此它发送和结束的是数据包。
接收发送数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| DatagramChannel channel = DatagramChannel.open(); //打开 channel.socket().bind(new InetSocketAddress(100)); //绑定接口
//接收数据 ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); channel.receive(buf);
//发送数据 ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(text.getBytes()); buf.flip(); int bytesSent = channel.send(buf, new InetSocketAddress(ip, 100));
|
Pipe
管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
读写数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Pipe pipe = Pipe.open(); //打开通道 Pipe.SinkChannel sinkChannel = pipe.sink(); String newData = "..."; ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes());
buf.flip();
//写入数据 while(buf.hasRemaining()) { sinkChannel.write(buf); }
//读取数据 Pipe.SourceChannel sourceChannel = pipe.source(); ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = sourceChannel.read(buf);
|