非阻塞式IO
- 使用channel代替stream
- 使用selector監控多條channel
- 可以在一個線程裏處理多個channel I/O
Buffer解析
buffer既可以寫也可以讀,一開始我們向buffer寫入到了position位置個數據
現在想從buffer裏面讀出數據,調用buffer的flip()方法 調整爲讀模式
將position位置指向開始的位置。limit指向已有數據的尾部
讀完以後我們又想開始寫入數據到buffer,調用buffer的clear()方法,調整爲寫模式。limit指向capacity,position指向開始位置
clear()並沒有真正的清除數據只是調整了指針。
如果buffer未讀完。又想寫入。調用buffer的compact()方法,把未讀完的數據放到buffer前部,
將position指向未讀完數據的下面開始寫入
Channel解析
selector 解析
在selector上註冊channel,監聽channel的狀態
代碼示例
package main.java.com.founder.study.javaio.nio;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* Created by Founder on 2020/6/28.
*/
interface FileCopyRunner {
void copyFile(File source, File target);
}
public class FileCopyDemo{
public static void main(String[] args) {
FileCopyRunner noBufferStreamCopy = new FileCopyRunner() {
@Override
public void copyFile(File source, File target) {
FileInputStream in =null;
FileOutputStream os = null;
try {
in = new FileInputStream(source);
os = new FileOutputStream(target);
int result ;
while( (result = in.read()) != -1){
os.write(result);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
close(os);
close(in);
}
}
};
FileCopyRunner bufferStreamCopy = new FileCopyRunner() {
@Override
public void copyFile(File source, File target) {
FileInputStream in =null;
FileOutputStream os = null;
byte[] buffer =new byte[1024];
try {
in = new FileInputStream(source);
os = new FileOutputStream(target);
int len ;
while( (len = in.read(buffer)) != -1){
os.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
close(os);
close(in);
}
}
};
FileCopyRunner nioBufferCopy = new FileCopyRunner() {
@Override
public void copyFile(File source, File target) {
FileChannel fin =null;
FileChannel fout = null ;
try {
fin= new FileInputStream(source).getChannel();
fout = new FileOutputStream(target).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 從channel中讀入數據寫進buffer
while (fin.read(buffer)!= -1){
//將buffer調整爲讀模式
buffer.flip();
//從buffer中讀出寫進寫進文件
while (buffer.hasRemaining()){
fout.write(buffer);
}
//循環讀完buffer後將buffer轉爲寫模式
buffer.clear();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
close(fin);
close(fout);
}
}
};
FileCopyRunner nioTransferCopy = new FileCopyRunner() {
@Override
public void copyFile(File source, File target) {
FileChannel fin =null;
FileChannel fout = null;
try {
fin = new FileInputStream(source).getChannel();
fout = new FileOutputStream(target).getChannel();
Long transferd = 0L;
while(transferd != fin.size()){
transferd +=fin.transferTo(0,fin.size(),fout);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
close(fin);
close(fout);
}
}
};
}
private static void close(Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}