JAVA高階基礎(48)---使用通道完成檔案資料傳輸
阿新 • • 發佈:2018-12-15
通道(Channel):傳輸資料
由 java.nio.channels 包定義的。Channel表示IO源與目標開啟的連結。Channel類似於傳統的“流”。只不過Channel本身不能直接訪問資料,Channel只能與 Buffer 進行互動
IO 改進示意圖
DMA(直接儲存器訪問)
Java 為 Channel 介面提供的最主要實現類如下:
- FileChannel:用於讀取、寫入、對映和操作檔案的通道。
- DatagramChannel:通過 UDP 讀寫網路中的資料通道。
- SocketChannel:通過 TCP 讀寫網路中的資料。
- ServerSocketChannel:可以監聽新進來的 TCP 連線,對每一個新進來的連線都會建立一個 SocketChannel。
獲取通道
本地IO:
FileInputStream/FileOutPutStream
RandomAccessFile
網路IO:
socket
ServerSocket
DatagramSocket
獲取通道的其他方式是:
- jdk1.7 使用 Files 類的靜態方法 newByteChannel() 獲取位元組通道。
- jdk1.7 通過通道的靜態方法 open() 開啟並返回指定通道
使用通道進行資料傳輸
FileInputStream / FileOutputStream 的getChannel()
FileChannle的open(Path path,OpenOpertion ... oo)方法來開啟通道
package org.lanqiao.channel; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /* * 通過本地IO獲取通道 進行資料傳輸 */ public class ChannelDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream(new File("Notes.txt")); FileOutputStream fos = new FileOutputStream(new File("copy.txt")); //開闢通道 FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel(); //分配緩衝區 ByteBuffer buffer = ByteBuffer.allocate(1024); //迴圈將輸入讀入到緩衝區 while((inChannel.read(buffer)) != -1) { //將緩衝區有讀模式切換到寫模式 buffer.flip(); //將緩衝區中的資料通過輸出通道寫出到膜裱 outChannel.write(buffer); //清空緩衝區 buffer.clear(); } //關閉通道 inChannel.close(); outChannel.close(); } }
package org.lanqiao.channel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class ChannelDemo2 {
public static void main(String[] args) throws IOException {
//開啟檔案輸入通道
FileChannel inChannel = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
//開啟檔案輸出通道
FileChannel outChannel = FileChannel.open(Paths.get("copy2.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
ByteBuffer buf = ByteBuffer.allocate(1024);
while((inChannel.read(buf)) != -1) {
buf.flip();
outChannel.write(buf);
buf.clear();
}
inChannel.close();
outChannel.close();
}
}
package org.lanqiao.channel;
import java.io.IOException;
import java.io.InputStream;
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;
/*
* 使用直接緩衝區(記憶體對映檔案)完成檔案複製
*/
public class ChannelDemo3 {
public static void main(String[] args) throws IOException {
FileChannel inChannel = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("copy3.txt"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//ByteBuffer buf = ByteBuffer.allocateDirect(1024);
//建立記憶體對映檔案
MappedByteBuffer inMap = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMap = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
byte[] buf = new byte[inMap.limit()];
inMap.get(buf);
outMap.put(buf);
inChannel.close();
outChannel.close();
}
}
package org.lanqiao.channel;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/*
* 通道之間直接進行檔案傳輸(直接緩衝區)
*/
public class ChannelDemo4 {
public static void main(String[] args) throws IOException {
FileChannel inChannle = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("copy5.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
//inChannle.transferTo(0, inChannle.size(), outChannel);
outChannel.transferFrom(inChannle, 0, inChannle.size());
inChannle.close();
outChannel.close();
}
}