Java NIO 通道
二、通道的主要實現類
java.nio.channels.Channel 介面:
|--FileChannel
|--SocketChannel
|--ServerSocketChannel
|--DatagramChannel
三、獲取通道
1. Java 針對支援通道的類提供了 getChannel() 方法
本地 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
編碼:字串 -> 位元組陣列
解碼:位元組陣列 -> 字串
//利用通道完成檔案的複製(非直接緩衝區)
public void test1(){
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
//①獲取通道
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fis = new FileInputStream("d:/1.mkv");
fos = new FileOutputStream("d:/2.mkv");
inChannel = fis.getChannel();
outChannel = fos.getChannel();
//②分配指定大小的緩衝區
ByteBuffer buf = ByteBuffer.allocate(1024);
//③將通道中的資料存入緩衝區中
while(inChannel.read(buf) != -1){
buf.flip(); //切換讀取資料的模式
//④將緩衝區中的資料寫入通道中
outChannel.write(buf);
buf.clear(); //清空緩衝區
}
} catch (IOException 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));
}
//使用通道完成檔案的複製(直接緩衝區 記憶體對映檔案)
public void test2() throws IOException{//2127-1902-1777
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
//記憶體對映檔案
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));
}
//通道之間的資料傳輸(直接緩衝區)
public void test3() throws IOException{
FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// inChannel.transferTo(0, inChannel.size(), outChannel);
outChannel.transferFrom(inChannel, 0, inChannel.size());
inChannel.close();
outChannel.close();
}
//分散和聚集
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[] 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 raf2 = new RandomAccessFile("2.txt", "rw");
FileChannel channel2 = raf2.getChannel();
channel2.write(bufs);
}
//獲取所有字符集
public void test5(){
Map<String, Charset> map = Charset.availableCharsets();
Set<Entry<String, Charset>> set = map.entrySet();
for (Entry<String, Charset> entry : set) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
//字符集
public void test6() throws IOException{
Charset cs1 = Charset.forName("GBK");
//獲取編碼器
CharsetEncoder ce = cs1.newEncoder();
//獲取解碼器
CharsetDecoder cd = cs1.newDecoder();
CharBuffer cBuf = CharBuffer.allocate(1024);
cBuf.put("Java NIO學習!");
cBuf.flip();
//編碼
ByteBuffer bBuf = ce.encode(cBuf);
for (int i = 0; i < 12; i++) {
System.out.println(bBuf.get());
}
//解碼
bBuf.flip();
CharBuffer cBuf2 = cd.decode(bBuf);
System.out.println(cBuf2.toString());
System.out.println("------------------------------------------------------");
Charset cs2 = Charset.forName("GBK");
bBuf.flip();
CharBuffer cBuf3 = cs2.decode(bBuf);
System.out.println(cBuf3.toString());
}
相關文章
- Java NIO:通道Java
- Java NIO 之 Channel(通道)Java
- Java-NIO之Channel(通道)Java
- Java NIO 檔案通道 FileChannel 用法Java
- javaNIO實戰4----> java NIO的通道Channel實戰Java
- Java NIO.2系列文章之非同步通道API入門Java非同步API
- Java NIO系列教程(五) 通道之間的資料傳輸Java
- nio再學習之通道channel
- Java NIOJava
- JAVA NIO BufferJava
- JAVA 探究NIOJava
- Java NIO SocketChannelJava
- Java NIO - BufferJava
- Java NIO - 群聊Java
- Java NIO filesJava
- JDK 17的外部儲存器訪問和Nio通道非同步化 – Inside.javaJDK非同步IDEJava
- Java NIO之SelectorJava
- Java NIO之BufferJava
- Java IO 和 NIOJava
- java NIO SocketClinet ServerSocketJavaServer
- Java NIO 概覽Java
- Java Socket 之 NIOJava
- 詳解 Java NIOJava
- 淺析Java NIOJava
- Asyncdb(三):Java NIOJava
- Java IO之NIOJava
- Java NIO Channel 使用Java
- Java BIO,NIO,AIOJavaAI
- Java nio記錄Java
- 【譯】Java NIO 簡明教程系列之 NIO 概述Java
- day2 Java NIOJava
- 深入的聊聊 Java NIOJava
- Java NIO 程式碼示例Java
- java BIO、NIO學習Java
- Java NIO - Channel 與 SelectorJava
- Java NIO - 零拷貝Java
- Java NIO - 零複製Java
- Java NIO:選擇器Java
- Java NIO:緩衝區Java