package com.yjh.nio.day01;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
/**
* 一、通道(Channel):用于源节点和目标节点的连接。在JAVA NIO中负责缓冲区中数据传输。
* Channel本身不存储数据,因此需要配合缓冲区进行传输。
*
* 二、通道的主要实现类
* java.nio.channels.Channel 接口:
* |--FileChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* 三、获取通道
* 1.JAVA针对支持通道的类提供了getChannels()方法
* 本地IO:
* FileInputStream/FileOutputStream
* RandomAccessFile
* 网络IO:
* Socket
* ServerSocket
* DatagramSocket
* 2.在JDK 1.7中的NIO.2针对各个通过提供了静态方法open()
* 3.在JDK 1.7中的NIO.2的Files工具类的newByteChannel()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集(Gather)
* 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
* 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
*
* 六、字符集:Charset
* 编码:字符串->字节数组
* 解码:字节数组->字符串
*
* @author ye.jinhui
* @create 2017-02-18 22:22
*/
public class TestChannel {
//字符集
@Test
public void test6() throws CharacterCodingException {
Charset cs1 = Charset.forName("GBK");
//获取编码器
CharsetEncoder ce = cs1.newEncoder();
//获取解码器
CharsetDecoder cd = cs1.newDecoder();
CharBuffer cBuf = CharBuffer.allocate(1024);
cBuf.put("叶金辉最牛!");
cBuf.flip();
//编码
ByteBuffer bBuf = ce.encode(cBuf);
for(int i=0;i<12;i++) {
System.out.println(bBuf.get());
}
//解码
bBuf.flip();
System.out.println("---------------------");
CharBuffer cBuf2 = cd.decode(bBuf);
System.out.println(cBuf2.toString());
Charset cs2 = Charset.forName("GBK");
bBuf.flip();
CharBuffer cBuf3 = cs2.decode(bBuf);
System.out.println(cBuf3.toString());
}
@Test
public void test5() {
Map<String,Charset> map = Charset.availableCharsets();
Set<Map.Entry<String,Charset>> set = map.entrySet();
for (Map.Entry<String,Charset> entry : set) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
//分散和聚集
@Test
public void test4() throws IOException {
RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw");
//1.获取通道
FileChannel channel1 = raf1.getChannel();
//2.分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);
//3.分散读取
ByteBuffer[] dsts = {buf1,buf2};
channel1.read(dsts);
for (ByteBuffer byteBuffer : dsts) {
byteBuffer.flip();
}
System.out.println(new String(dsts[0].array(),0,dsts[0].limit()));
System.out.println("--------------------------------------");
System.out.println(new String(dsts[1].array(),0,dsts[1].limit()));
//4.聚集写入
RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw");
FileChannel channel2 = raf2.getChannel();
channel2.write(dsts);
channel2.close();
channel1.close();
}
//通道之间的数据传输(直接缓冲区)
@Test
public void test3() {
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("G:/futangdaohuo.rmvb"),StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("G:/futangdaohuo2.rmvb"),StandardOpenOption.WRITE,
StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
// inChannel.transferTo(0,inChannel.size(),outChannel);
outChannel.transferFrom(inChannel,0,inChannel.size());
}catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//使用直接缓冲区完成文件的复制(内存映射文件)
@Test
public void test2() {
long start = System.currentTimeMillis();
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("G:/futangdaohuo.rmvb"), StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("G:/futangdaohuo2.rmvb"),StandardOpenOption.READ,StandardOpenOption.WRITE,
StandardOpenOption.CREATE);
//内存映射文件
MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY,0,inChannel.size());
MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE,0,inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
}catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start) + "ms");
}
//利用通道完成文件的复制(非直接缓冲区)
@Test
public void test1() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fis = new FileInputStream("G:/futangdaohuo.rmvb");
fos = new FileOutputStream("G:/futangdaohuo2.rmvb");
//①.获取通道
inChannel = fis.getChannel();
outChannel = fos.getChannel();
//②.分配指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
//③.将通道中的数据存入缓冲区
while((inChannel.read(buf)) != -1) {
buf.flip();
//④.将缓冲区中的数据写到通道
outChannel.write(buf);
buf.clear();//清空缓冲区
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start) + "ms");
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
/**
* 一、通道(Channel):用于源节点和目标节点的连接。在JAVA NIO中负责缓冲区中数据传输。
* Channel本身不存储数据,因此需要配合缓冲区进行传输。
*
* 二、通道的主要实现类
* java.nio.channels.Channel 接口:
* |--FileChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* 三、获取通道
* 1.JAVA针对支持通道的类提供了getChannels()方法
* 本地IO:
* FileInputStream/FileOutputStream
* RandomAccessFile
* 网络IO:
* Socket
* ServerSocket
* DatagramSocket
* 2.在JDK 1.7中的NIO.2针对各个通过提供了静态方法open()
* 3.在JDK 1.7中的NIO.2的Files工具类的newByteChannel()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集(Gather)
* 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
* 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
*
* 六、字符集:Charset
* 编码:字符串->字节数组
* 解码:字节数组->字符串
*
* @author ye.jinhui
* @create 2017-02-18 22:22
*/
public class TestChannel {
//字符集
@Test
public void test6() throws CharacterCodingException {
Charset cs1 = Charset.forName("GBK");
//获取编码器
CharsetEncoder ce = cs1.newEncoder();
//获取解码器
CharsetDecoder cd = cs1.newDecoder();
CharBuffer cBuf = CharBuffer.allocate(1024);
cBuf.put("叶金辉最牛!");
cBuf.flip();
//编码
ByteBuffer bBuf = ce.encode(cBuf);
for(int i=0;i<12;i++) {
System.out.println(bBuf.get());
}
//解码
bBuf.flip();
System.out.println("---------------------");
CharBuffer cBuf2 = cd.decode(bBuf);
System.out.println(cBuf2.toString());
Charset cs2 = Charset.forName("GBK");
bBuf.flip();
CharBuffer cBuf3 = cs2.decode(bBuf);
System.out.println(cBuf3.toString());
}
@Test
public void test5() {
Map<String,Charset> map = Charset.availableCharsets();
Set<Map.Entry<String,Charset>> set = map.entrySet();
for (Map.Entry<String,Charset> entry : set) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
//分散和聚集
@Test
public void test4() throws IOException {
RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw");
//1.获取通道
FileChannel channel1 = raf1.getChannel();
//2.分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);
//3.分散读取
ByteBuffer[] dsts = {buf1,buf2};
channel1.read(dsts);
for (ByteBuffer byteBuffer : dsts) {
byteBuffer.flip();
}
System.out.println(new String(dsts[0].array(),0,dsts[0].limit()));
System.out.println("--------------------------------------");
System.out.println(new String(dsts[1].array(),0,dsts[1].limit()));
//4.聚集写入
RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw");
FileChannel channel2 = raf2.getChannel();
channel2.write(dsts);
channel2.close();
channel1.close();
}
//通道之间的数据传输(直接缓冲区)
@Test
public void test3() {
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("G:/futangdaohuo.rmvb"),StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("G:/futangdaohuo2.rmvb"),StandardOpenOption.WRITE,
StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
// inChannel.transferTo(0,inChannel.size(),outChannel);
outChannel.transferFrom(inChannel,0,inChannel.size());
}catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//使用直接缓冲区完成文件的复制(内存映射文件)
@Test
public void test2() {
long start = System.currentTimeMillis();
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("G:/futangdaohuo.rmvb"), StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("G:/futangdaohuo2.rmvb"),StandardOpenOption.READ,StandardOpenOption.WRITE,
StandardOpenOption.CREATE);
//内存映射文件
MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY,0,inChannel.size());
MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE,0,inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
}catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start) + "ms");
}
//利用通道完成文件的复制(非直接缓冲区)
@Test
public void test1() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fis = new FileInputStream("G:/futangdaohuo.rmvb");
fos = new FileOutputStream("G:/futangdaohuo2.rmvb");
//①.获取通道
inChannel = fis.getChannel();
outChannel = fos.getChannel();
//②.分配指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
//③.将通道中的数据存入缓冲区
while((inChannel.read(buf)) != -1) {
buf.flip();
//④.将缓冲区中的数据写到通道
outChannel.write(buf);
buf.clear();//清空缓冲区
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start) + "ms");
}
}