channel基础
打开通道
有多种方式可用开启通道。
SocketChannel socketChannel=SocketChannel.open()
socketChannel.connect(new InetSocketAddress("localhost", 9999))
ServerSocketChannel serverSocketChannel=ServerSocketChannel.open()
serverSocketChannel.socket().bind(new InetSocketAddress(8888))
DatagramChannel datagramChannel=DatagramChannel.open()
FileInputStream fileInputStream=new FileInputStream("test.txt")
FileChannel fileChannel=fileInputStream.getChannel()
使用通道
ReadableByteChannel : 可读通道
WritableByteChannel :可写通道
ReadableByteChannel in=Channels.newChannel(System.in)
WritableByteChannel out=Channels.newChannel(System.out)
ByteBuffer buffer=ByteBuffer.allocateDirect(6)
while (in.read(buffer) != -1) {
buffer.flip()
while (buffer.hasRemaining()) {
out.write(buffer)
}
buffer.clear()
}
gather/scatter
scatter : 读取多个buffers中的数据
gather : 将数据聚集写入到buffers中
public interface ScatteringByteChannel
extends ReadableByteChannel
{
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
public long read(ByteBuffer[] dsts) throws IOException;
}
public interface GatheringByteChannel
extends WritableByteChannel
{
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
public long write(ByteBuffer[] srcs) throws IOException;
}
package com.socket.channel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
/**
* Created by guoyao on 2017/7/16.
*/
public class TestGather {
private static String str1 = "test1";
private static String str2 = "test2";
private static String str3 = "test3";
private static String str4 = "test4";
private static String str5 = "test5";
private static String str6 = "test6";
private static ByteBuffer[] getBuffers() {
String[] sArr={str1, str2, str3, str4, str5, str6};
ByteBuffer[] buffers=new ByteBuffer[6];
int i = 0 ;
for (String str : sArr) {
ByteBuffer buffer=ByteBuffer.allocate(str.length());
buffers[i]=buffer.put(str.getBytes());
buffer.flip();
i ++;
}
return buffers;
}
private static ByteBuffer[] getEmptyBuffers() {
ByteBuffer[] buffers=new ByteBuffer[6];
for (int i = 0 ; i < 6 ; i ++) {
ByteBuffer buffer=ByteBuffer.allocate(15);
buffers[i]=buffer;
}
return buffers;
}
public static void main(String[] args){
try {
File file=new File("C:\\Users\\liberal\\Desktop\\test.txt");
FileInputStream fin=new FileInputStream(file);
ScatteringByteChannel scatterChannel =fin.getChannel();
ByteBuffer[] buffers=getEmptyBuffers();
while (scatterChannel.read(buffers,0,2) > 0) ;
StringBuilder stringBuilder=new StringBuilder();
for (ByteBuffer buffer : buffers) {
if (buffer == null) {
continue;
}
buffer.flip();
while (buffer.hasRemaining()) {
stringBuilder.append((char)buffer.get());
}
buffer.clear();
}
System.out.println(" read over stringBuilder = " + stringBuilder.toString());
fin.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void testGather() {
try {
File file=new File("C:\\Users\\liberal\\Desktop\\test.txt");
FileOutputStream fout=new FileOutputStream(file);
GatheringByteChannel gatherChinnel =fout.getChannel();
ByteBuffer[] buffers=getBuffers();
while (gatherChinnel.write(buffers) > 0) ;
System.out.println(" write over ");
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件通道FileChannel
访问文件
private static void testPosition() throws IOException {
RandomAccessFile randomAccessFile=new RandomAccessFile("C:\\Users\\liberal\\Desktop\\test.txt", "r")
randomAccessFile.seek(1000)
FileChannel fileChannel=randomAccessFile.getChannel()
System.out.println("file pos: " + fileChannel.position())
randomAccessFile.seek(500)
System.out.println("file pos: " + fileChannel.position())
fileChannel.position(200)
System.out.println("file pos: " + randomAccessFile.getFilePointer())
}
// file hole 0 ~ 500 hole 500 ~ 5000000 hole
private static void testFileHole() throws IOException {
File file=new File("C:\\Users\\liberal\\Desktop\\test.txt")
RandomAccessFile randomAccessFile=new RandomAccessFile(file, "rw")
FileChannel channel=randomAccessFile.getChannel()
ByteBuffer buffer=ByteBuffer.allocateDirect(100)
putData(0, buffer, channel)
putData(5000000, buffer, channel)
putData(50000, buffer, channel)
System.out.println("Wrote temp file '" + file.getPath() + "', size=" + channel.size())
channel.close()
randomAccessFile.close()
}
private static void putData(int position, ByteBuffer buffer, FileChannel channel) throws IOException {
String string="*<-- location " + position
buffer.clear()
buffer.put(string.getBytes("US-ASCII"))
buffer.flip()
channel.position(position)
channel.write(buffer)
}
channel-to-channel
直接通过通道对通道传输(仅限于fileChannel)
WritableByteChannel wbc=Channels.newChannel(System.out)
String str1 = "C:\\Users\\wb-ygy260316\\Desktop\\test1.txt"
String str2 = "C:\\Users\\wb-ygy260316\\Desktop\\test2.txt"
String[] sArr={str1, str2}
for (String file : sArr) {
FileInputStream fin=new FileInputStream(file)
FileChannel fc=fin.getChannel()
fc.transferTo(0, fc.size(), wbc)
fin.close()
fc.close()
}