Java NIO之通道Channel代码实例
文章目录
- 代码实例
- 控制台输出结果
相关Java NIO详解: Java NIO详解
代码实例
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** * 通道channel: * 用于源节点与目标节点的连接,本身不负责存储数据,主要是配合缓冲区,负责数据的运输。 * 1.主要的实现类: * java.nio.channels.Channel接口 * --用于本地文件: * -FileChannel * --用于网络 * -SocketChannel一般用于客户端,TCP协议 * -ServerSocketChannel一般用于服务端,TCP协议 * -DatagramChannel基于UDP协议,主要用于发送和接收数据包 * 2.获取通道Channel的方法 * (1)java针对支持通道的类提供了getChannel()方法 * --本地文件 * FileInputStream/FileOutoutStream * RandomAccessFile * --网络传输 * Socket * ServerSocket * DatagramSocket * (2)在JDK1.7中的NIO2针对各个通道提供了静态方法open() * (3)在JDK1.7中的NIO2中Files工具类newByteChannel() * 3.通道之间的传输,两种方法 * transferForm() * transferTo() * */
public class ChannelDome {
/** * main测试,利用线程池进行创建线程并运行。 */
public static void main(String[] args) {
//1.创建可重用固定线程数量的线程池
ExecutorService executorService= Executors.newFixedThreadPool(10);
//System.out.println(executorService.getClass());//查看调用了那个接口的对应实现类。
//2.执行指定的线程的操作,需要提供的是Runnable接口或Callable接口实现类的对象
copyFileThread1 thread1=new copyFileThread1();
copyFileThread2 thread2=new copyFileThread2();
channelWriteAndRead thread3=new channelWriteAndRead();
channelTransfer thread4=new channelTransfer();
executorService.execute(thread1);
executorService.execute(thread2);
executorService.execute(thread3);
executorService.execute(thread4);
//executorService.submit();
executorService.shutdown();
}
/** * 1.利用通道进行本地文件的复制功能(非直接缓冲区) * @param copyFrom * @param copyTo * @return boolean */
public boolean copyFileByChannel(String copyFrom,String copyTo) throws IOException {
long start=System.currentTimeMillis();
boolean result=false;
FileInputStream inputStream=null;
FileOutputStream outputStream=null;
FileChannel inputChannel=null;
FileChannel outputChannel=null;
try {
//1.获取本地输入输出流
inputStream = new FileInputStream(copyFrom);
outputStream = new FileOutputStream(copyTo);
//2.获取本地对应输入输出通道
inputChannel = inputStream.getChannel();
outputChannel = outputStream.getChannel();
//3.分配指定大小的缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
//4.将输入通道中的数据存入缓冲区
while (inputChannel.read(byteBuffer) != -1) { //从当前通道position读取数据到缓冲区,若到达末尾,返回-1
byteBuffer.flip();//切换到读取数据模式
//5.将缓冲区的数据写入到输出通道中
outputChannel.write(byteBuffer);
byteBuffer.clear();//清空缓冲区
result=true;
}
}finally {
if(inputStream !=null){
inputStream.close();
}
if(inputChannel !=null){
inputChannel.close();
}
if(outputChannel !=null){
outputChannel.close();
}
if(outputStream !=null){
outputStream.close();
}
}
long end=System.currentTimeMillis();
System.out.println("非缓冲区复制文件耗时:"+(end-start));
return result;
}
/** * 2.利用通道进行本地文件的复制功能(直接缓冲区,利用内存映射文件) * @param copyFrom * @param copyTo * @return boolean */
public boolean copyFileByChannel2Direct(String copyFrom,String copyTo) throws IOException {
long start=System.currentTimeMillis();
//1.获取输入输出通道
FileChannel inputChannel= FileChannel.open(Paths.get(copyFrom), StandardOpenOption.READ);
FileChannel outputChannel=FileChannel.open(Paths.get(copyTo),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//2.获取内存映射文件
MappedByteBuffer inMappedBuf=inputChannel.map(FileChannel.MapMode.READ_ONLY,0,inputChannel.size());
MappedByteBuffer outMappedBuf=outputChannel.map(FileChannel.MapMode.READ_WRITE,0,inputChannel.size());
//3.直接对缓冲区进行读写操作
byte[] dst=new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
//4.关闭输入输出通道
inputChannel.close();
outputChannel.close();
long end =System.currentTimeMillis();
System.out.println("直接缓冲区复制的耗时:"+(end-start));
return true;
}
/** * 3.通道之间的数据传输(直接缓冲区) * @param copyFrom * @param copyTo * @return boolean */
public boolean copyFileByChannel2Transfer(String copyFrom,String copyTo) throws IOException {
FileChannel inChannel=FileChannel.open(Paths.get(copyFrom),StandardOpenOption.READ);
FileChannel outChannel=FileChannel.open(Paths.get(copyTo),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//1.将通道中的字节数据传输到指定通道,transferTo()
inChannel.transferTo(0,inChannel.size(),outChannel);
//2.从指定通道中获取自己数据到通道中,transferFrom()
//outChannel.transferFrom(inChannel,0,inChannel.size());
return true;
}
/** * 4.通道的分散和聚合 *分散读取:将通道的数据读取到多个缓冲区Bufer中 * 聚集写入:将多个缓冲区的数据聚集写到通道Channel中 * @param writeFlie * @param readFlie */
public void channelWriteAndRead(String writeFlie,String readFlie) throws IOException {
//1.读取指定文件
RandomAccessFile randomAccessFile=new RandomAccessFile(readFlie,"rw");
//2.获取本地文件通道
FileChannel fileChannel=randomAccessFile.getChannel();
//3.分配指定大小的缓冲区
ByteBuffer buf1=ByteBuffer.allocate(1024);//设置多大就缓存多大
ByteBuffer buf2=ByteBuffer.allocate(1024);
//4.分散读取
ByteBuffer[] bufs={ buf1,buf2};
fileChannel.read(bufs);
for(ByteBuffer byteBuffer:bufs){
byteBuffer.flip();
System.out.println("每个缓冲区的数据如下:");
System.out.println(new String(byteBuffer.array(),0,byteBuffer.limit()));
}
//5.聚集写入(指定文件)
RandomAccessFile randomAccessFile1=new RandomAccessFile(writeFlie,"rw");//指定写到那个文件下
FileChannel fileChannel1=randomAccessFile1.getChannel();
fileChannel1.write(bufs);
}
}
//创建线程1测试,非缓冲区文件复制
class copyFileThread1 implements Runnable{
ChannelDome channelDome=new ChannelDome();
String copyFrom="G:\\copyFromFile\\copyForm.log";
String copyTo="H:\\copyToFile\\NoDirect\\copyTo1.log";
@Override
public void run() {
try {
System.out.println(Thread.currentThread() +"当前线程正在执行利用非缓冲区本地文件复制功能");
channelDome.copyFileByChannel(copyFrom,copyTo);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建线程2测试,
class copyFileThread2 implements Runnable{
ChannelDome channelDome =new ChannelDome();
String copyFrom="G:\\copyFromFile\\copyForm.log";
String copyTo="H:\\copyToFile\\Direct\\copyTo2.log";
@Override
public void run() {
try {
System.out.println(Thread.currentThread() +"当前线程正在执行利用缓冲区本地文件复制功能");
channelDome.copyFileByChannel2Direct(copyFrom,copyTo);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//通道的分散读取和聚集写入线程测试
class channelWriteAndRead implements Runnable{
ChannelDome channelDome=new ChannelDome();
String writeFile="G:\\copyFromFile\\copyForm.log";
String readFile="H:\\copyToFile\\Read\\read.log";
@Override
public void run() {
try {
System.out.println(Thread.currentThread() +"当前线程正在执行通道的分散读取和聚集写入线程功能");
channelDome.channelWriteAndRead(readFile,writeFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//通道之间的传输线程测试
class channelTransfer implements Runnable{
ChannelDome channelDome=new ChannelDome();
String copyForm="G:\\copyFromFile\\copyForm.log";
String copyTo="H:\\copyToFile\\transfer\\transfer.log";
@Override
public void run() {
try {
System.out.println(Thread.currentThread() +"当前线程正在执行通道之间的传输线程功能");
channelDome.copyFileByChannel2Transfer(copyForm,copyTo);
} catch (IOException e) {
e.printStackTrace();
}
}
}
还没有评论,来说两句吧...