BIO = blocking io
AIO = Asynchronous IO
从内存读取到写入--输出
从外部到内存 -- 输入
OutputStream //文件不存在则自动创建
try {
OutputStream outputStream = new FileOutputStream("text.txt");
outputStream.write('a');
outputStream.write('b');
} catch (IOException e) {
throw new RuntimeException(e);
}
读取,写入实在内存开辟空间,然后进行读写,需要及时释放
Reader ---- BufferReader
try (InputStream inputStream = new FileInputStream("text.txt")){ //1
Reader reader = new InputStreamReader(inputStream); //2
BufferedReader bufferedReader = new BufferedReader(reader);// 3,增加buffer
System.out.println(bufferedReader.readLine());
inputStream.close();
} catch (IOException e) {
//close
throw new RuntimeException(e);
} finally {
//close
}
嵌套了三层
BufferRead 预先读 增加性能
默认8192个字节
private static int defaultCharBufferSize = 8192; private static int defaultExpectedLineLength = 80;
bufferedOutputStream.write 需要主动flush 或者等缓冲区 8192字节满的时候才会写入,因为有缓冲
关闭close 的时候也会自动flush
try (OutputStream outputStream = new FileOutputStream("text.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {}//通过这种方式也会自动flush
Android copy文件 FileUtils.copy
copy文件
try (InputStream inputStream = new FileInputStream("text.txt");
OutputStream outputStream = new FileOutputStream("text1.txt")) {
byte[] data = new byte[1024]; //每次读的字节
int read;//读取的个数
while ((read = inputStream.read(data)) != -1) {
//读取是个循环过程,读多少就写入多少,如果读完就是-1
//写入字节,从起始位置到读取的数量
outputStream.write(data, 0, read);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
可以通过buffer 减少其交互,增加性能
try (InputStream inputStream = new BufferedInputStream(new FileInputStream("text.txt"));
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream("text1.txt"))) {
byte[] data = new byte[1024];
int read;
while ((read = inputStream.read(data)) != -1) {
outputStream.write(data, 0, read);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
不然每次读写交互频率较高
Socket:
try (Socket socket = new Socket("sougou.com", 80);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
// getOutputStream 写入
//getInputStream 读取
writer.write("GET / HTTP/1.1\n" + "HOST: www.example.com\n\n"); //请求报文
writer.flush(); //提交
String message;
while ((message = reader.readLine()) != null) {
//读取相应内容
System.out.println(message);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
NIO
传统IO Stream /管道
NIO Channel/ 双向
NIO Buffer
Buffer 可以操作,强制使用
非阻塞式 //支持非阻塞式,默认阻塞式,只有网络交互时支持非阻塞式,文件交互不支持
try {
//capacity limit 上限,移动位置 一般不变
//position 位置,指针位置
//r 读权限,w 写入
RandomAccessFile randomAccessFile = new RandomAccessFile("text.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //目前不支持读取
fileChannel.read(byteBuffer);
//这两行等同于下面一行
byteBuffer.limit(byteBuffer.position());
byteBuffer.position(0);
//等同于这种写法
byteBuffer.flip();
System.out.println();
} catch (IOException e) {
throw new RuntimeException(e);
}
每次读完都要clear
byteBuffer.clear();
阻塞式NIO
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(80));
SocketChannel socketChannel = serverSocketChannel.accept();//阻塞式
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
socketChannel.read(byteBuffer);
byteBuffer.flip();
System.out.println(byteBuffer);
byteBuffer.clear();
} catch (IOException e) {
throw new RuntimeException(e);
}
非阻塞式
serverSocketChannel.configureBlocking(false); //默认true 阻塞式
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(80));
serverSocketChannel.configureBlocking(false);//非阻塞
Selector selector = Selector.open();//选择器
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//注册
while (true){
selector.select();//选择
for (SelectionKey key : selector.selectedKeys()){
if (key.isAcceptable()){
SocketChannel socketChannel = serverSocketChannel.accept();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (socketChannel.read(byteBuffer) != -1){
byteBuffer.flip();
System.out.println(byteBuffer);
byteBuffer.clear();
}
}else break;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
OKIO
基于NIO进行包装
也是基于管道 ,单向 Source 和 Sink
支持Buffer /可以对Buffer 进行操作 / 不强制使用Buff
read(buffer) buffer是写的操作
从buffer取出是读操作,buffer读是写操作
File().copyTO