package com.nio.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import org.junit.Test; /**
*
* @author fliay
*
* 一、通道(channel): 用于源节点与目标节点的连接。在JavaNIO中负责缓冲区中数据的传输。
* Channel本身不存在存数据,因此需要配合缓冲区进行传输。
*
* 二、通道的主要实体类
* |--FileChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* 三、获取通道 1.Java针对支持通道的类提供了getChannel()方法 本地IO:
* FileInputStream/FileOutputStream RandomAccessFile
*
* 网络IO
* |--Socket
* |--ServerSocket
* |--DatagramSocket
*
* 2.在JDK1.7中的NIO.2针对各个通道提供了静态方法open()
* 3.在JDK1.7中的NIO.2的file工具类的newByteChannel()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集()
*
*/
public class TestChannel { // 利用通道完成文件的复制
@Test
public void test1() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
// cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408 大小为3.42G
fis = new FileInputStream("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso");
fos = new FileOutputStream("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso");
// 1.获取通道
inChannel = fis.getChannel();
outChannel = fos.getChannel();
// 2.分配指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
// 3.将通道中的数据存入缓冲区中
while (inChannel.read(buf) != -1) {
// 切换到读取数据模式
buf.flip();
// 4.将缓冲区中的数据写入通道中
outChannel.write(buf);
// 情况缓冲区
buf.clear();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outChannel.close();
inChannel.close();
fos.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
long end = System.currentTimeMillis(); System.out.println("消耗时间为:" + (end - start));
}
// 消耗时间为:12651 // 使用直接缓冲区完成文件的复制(内存映射文件)
@Test
public void Test2() throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// long[] sizes = new long[3];
// 如果文件过长的话会报错 Size exceeds Integer.MAX_VALUE 可以通过对文件进行分批存
// sizes[0]=0;
// sizes[1]=inChannel.size()/2;
// sizes[2]=inChannel.size()-inChannel.size()/2;
// for(int i=0;i<sizes.length-1;i++){
// //内存映射文件
// MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY,
// sizes[i],sizes[i+1]);
// MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE,
// sizes[i],sizes[i+1]);
// //直接对缓冲区进行数据的读写操作
// byte[] dst = new byte[inMappedBuf.limit()];
// inMappedBuf.get(dst);
// outMappedBuf.put(dst);
// }
// 内存映射文件
MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
// 直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("消耗时间为:" + (end - start)); }// 执行时间6161 // 通道之间的数据传输
@Test
public void Test3() throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// inChannel.transferTo(0, inChannel.size(), outChannel);//执行时间为3957
// 但是文件为拷贝完,只拷贝了2/3
outChannel.transferFrom(inChannel, 0, inChannel.size());// 执行时间8313 成功拷贝
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("消耗时间为:" + (end - start));
} //分散和聚集
@Test
public void Test4() throws IOException{
RandomAccessFile ref1 = new RandomAccessFile("/Study/JavaSite/JaveNIO/src/main/java/com/nio/test/TestChannel.java","rw");
//1.获取通道
FileChannel channel1 = ref1.getChannel();
//2.分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);
//3.分散读取
ByteBuffer[] bufs ={buf1,buf2};
channel1.read(bufs);
for(ByteBuffer byteBuffer:bufs){
byteBuffer.flip();
}
System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
System.out.println("----------------------------------------");
System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));
//4.聚集写入
RandomAccessFile ref2 = new RandomAccessFile("/Study/JavaSite/JaveNIO/src/main/java/com/nio/test/TestChannel2.java","rw");
FileChannel channel2 = ref2.getChannel();
channel2.write(bufs); } }

  

JAVANIO通道的更多相关文章

  1. javaNio 通道和缓冲区

    /** * 大多数操作系统可以利用虚拟内存将文件或文件一部分映射到内存中,然后这个文件就可以被当做内存数组一样被访问:避免底层IO的开销<p> * [通道]是一种用于磁盘文件的一种抽象:& ...

  2. Java - NIO基础

    1. 概述 现在使用NIO的场景越来越多,很多技术框架都使用NIO技术,比如Tomcat,Jetty,Netty等. 传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer进行操 ...

  3. Java-NIO(五):通道(Channel)的数据传输与内存映射文件

    通道(Channel)的数据传输(采用非直接缓冲区) @Test public void testChannel() throws IOException { FileInputStream file ...

  4. Java-NIO(四):通道(Channel)的原理与获取

    通道(Channel): 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Chann ...

  5. Java-NIO之Channel(通道)

    1:Channel是什么 通道表示与实体的开放连接,例如硬件设备.文件.网络套接字或能够执行一个或多个不同 I/O 操作(例如读取或写入)的程序组件. 1.1:Channel与Stream的对比 St ...

  6. javaNIO(转载)

    (一) Java NIO 概述 Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Chan ...

  7. Java NIO SocketChannel套接字通道

    原文链接:http://tutorials.jenkov.com/java-nio/socketchannel.html 在Java NIO体系中,SocketChannel是用于TCP网络连接的套接 ...

  8. Java NIO Channel通道

    原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...

  9. javaNIO核心概念

    在java的阻塞IO中使用InputStream和outputStream来进行输入和输出,那么两种流是相互独立使用的,而且每次数据传输都要通过“用户态数据”向“os内核态数据”copy或从“os内核 ...

随机推荐

  1. java 线程二

    一.线程的优先级别 线程优先级别的使用范例: 1 package cn.galc.test; 2 3 public class TestThread6 { 4 public static void m ...

  2. 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---线程优先权(Thread priority)

    有没有过这样的经验?你坐在你的车子里,目的地还在好几公里之遥,而时间已经很晚了.你拼命想告诉那些挡住你去路的人们,今天这个约会对你是多么多么重要,能不能请他们统统--呃--滚到马路外?很不幸,道路系统 ...

  3. 你真的会阅读Java的异常信息吗?

    给出如下异常信息: java.lang.RuntimeException: level 2 exception at com.msh.demo.exceptionStack.Test.fun2(Tes ...

  4. Stochastic Gradient Descent

    一.从Multinomial Logistic模型说起 1.Multinomial Logistic 令为维输入向量; 为输出label;(一共k类); 为模型参数向量: Multinomial Lo ...

  5. 移动HTNL5前端框架—MUI

      前  言 JRedu 鉴于之前的很多前端框架(特别是响应式布局的框架),UI控件看起来太像网页,没有原生感觉,因此追求原生UI也是MUI的重要目标.MUI以iOS平台UI为基础,补充部分Andro ...

  6. zoj1002 Fire Net

    Fire Net Time Limit: 2 Seconds      Memory Limit: 65536 KB Suppose that we have a square city with s ...

  7. 使用binlog2sql做数据恢复的简单示例

    有时我们会遇到操作人员误删或者误更新数据的情况,这时我们迫切希望把原来的数据还原回来,今天我们介绍一个简单的工具来方便的实现此功能. 前提条件 在实现数据恢复之前,需要我们的MySQL满足以下配置条件 ...

  8. bind、apply与call

    bind.apply与call 先说观点:不论是bind.apply还是call,最大的好处就是代码复用. bind 在开发中,我们只有复用代码时,才会出现this指向需要改动的情况. 纵观bind的 ...

  9. Android基础知识02—安卓日志工具LogCat的五种方法

    --------Android 02-------- >>> Android的日志工具LogCat    五个方法,记录信息的级别不一样,从低到高为:    1.Log.v()-日志 ...

  10. java的windows自动化-自动运行java程序

    那么在一些工具齐全并且已经有了一定的写好的java程序的情况下(环境变量和软件见上一章http://www.cnblogs.com/xuezhezlr/p/7718273.html),如何自动化运行j ...