扔物线学习笔记总结
- 传统I/O
- NIO
- Okio
io 通过流,不是直接读
失去方便性,扩展灵活性
- 基本操作小例子,往文件里面输出数据的示例,不直接操作文件,通过“管子”操作
public class Main {
public static void main(String[] args) {
File file = new File("./a.txt");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write('a');
fileOutputStream.write('b');
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileOutputStream 读写二进制,字符串需要使用Reader,Writer
读写“插管子后”需要关闭,因为读写信息占用内存资源(例如读到哪个字节),需要释放,所以要及时关闭
成功失败都要关闭,传统方式在finally关闭 把变量在外面初始化
Java7开始,放在try后面括号里完成之后自动关闭,原因实现了 Closeable
字符流
相当于把管子插到字节流上
小结
Reader 是字符流
Buffer 是缓存,然后一起与文件交互
文件复制
Android Java FileUtils Kotlin copyto
的表皮下真正的代码
/**
* 文件复制
*/
private static void io5() {
try (
InputStream inputStream = new FileInputStream("./a.txt");
OutputStream outputStream = new FileOutputStream("./b.txt")
) {
byte[] bytes = new byte[1024];
int read;
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
IO 就是内存和外界的交互
常用的File 类
网络交互Socket IO,
做TCP链接,网站针对字符
客户端
public static void io6() {
try (
Socket socket = new Socket("rengwuxian.com", 80);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
) {
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) {
e.printStackTrace();
}
}
小结代码
package test.io;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) {
// io1();
// io2();
// io3();
// io4();
// io5();
// io6();
io7();
}
/**
* 写文件
*/
private static void io1() {
File file = new File("./a.txt");
try (OutputStream fileOutputStream = new FileOutputStream(file);) {
fileOutputStream.write('a');
fileOutputStream.write('b');
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读文件
*/
private static void io2() {
File file = new File("./a.txt");
try (InputStream fileInputStream = new FileInputStream(file)) {
//读的都是字节
System.out.println((char) fileInputStream.read());
System.out.println((char) fileInputStream.read());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读文件buffer
*/
private static void io3() {
File file = new File("./a.txt");
try (InputStream fileInputStream = new FileInputStream(file);
//读的都是字节
//第二层字节上字符,也可以使用FileReader一步到位 字符流
Reader reader = new InputStreamReader(fileInputStream);
//第三层 整行读 再套一层 buffer 增加buffer,一次多读一些defaultCharBufferSize 8*1024
BufferedReader bufferedReader = new BufferedReader(reader)
) {
System.out.println(bufferedReader.readLine());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写文件 buffer 缓冲需要flush
* 文件与内存交互性能低,所以buffer输出不同步
* close会自动flush
*/
private static void io4() {
File file = new File("./a.txt");
try (OutputStream fileOutputStream = new FileOutputStream(file);
OutputStream outputStream = new BufferedOutputStream(fileOutputStream);
) {
outputStream.write('a');
outputStream.write('p');
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 文件复制
*/
private static void io5() {
try (
InputStream inputStream = new FileInputStream("./a.txt");
OutputStream outputStream = new FileOutputStream("./b.txt")
) {
byte[] bytes = new byte[1024];
int read;
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* socket客户端
*/
public static void io6() {
try (
Socket socket = new Socket("rengwuxian.com", 80);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
) {
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) {
e.printStackTrace();
}
}
/**
* Socket 服务端
*/
public static void io7() {
try (
ServerSocket socketServer = new ServerSocket(80);
//阻塞等待访问,就一次哦
Socket socket = socketServer.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
) {
//先读后写根据读取内容写入,这里直接写入
writer.write("HTTP/1.1 200 OK\n" +
"Server: nginx/1.14.0 (Ubuntu)\n" +
"Date: Sun, 20 Jun 2021 09:17:34 GMT\n" +
"Content-Type: text/html\n" +
"Content-Length: 612\n" +
"Last-Modified: Fri, 11 Oct 2019 04:19:03 GMT\n" +
"Connection: keep-alive\n" +
"ETag: \"5da002b7-264\"\n" +
"Accept-Ranges: bytes\n" +
"\n" +
"\n" +
"\n" +
"\n" +
"Welcome to nginx! \n" +
"\n" +
"\n" +
"\n" +
"Test
\n" +
"If you see this page, the nginx web server is successfully installed and\n" +
"working. Further configuration is required.
\n" +
"\n" +
"For online documentation and support please refer to\n" +
"nginx.org.
\n" +
"Commercial support is available at\n" +
"nginx.com.
\n" +
"\n" +
"Thank you for using nginx.
\n" +
"\n" +
"\n" +
"\n" +
"Process finished with exit code 0\n\n");
//发送到网站
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO
- 传统I/O:Stream ;NIO:Channel(双向)
- NIO的Buffer
- Buffer可以被操作;强制使用Buffer;Buffer不好用
- 非阻塞式
- 只是【支持非阻塞式】,默认式阻塞式
- 只有网络交互支持非阻塞,文件交互不支持
/**
* NIO基本阻塞式读取
*/
public static void io8(){
//获取Channel
try {
RandomAccessFile file = new RandomAccessFile("./a.txt","r");
FileChannel channel =file.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
channel.read(byteBuffer);
//不能直接从ByteBuffer中读
// capacity 容量 position 位置 limit 限制
// byteBuffer.limit(byteBuffer.position());
// byteBuffer.position(0);
// byteBuffer.flip(); = byteBuffer.limit(byteBuffer.position());+ byteBuffer.position(0);
byteBuffer.flip();
System.out.println(Charset.defaultCharset().decode(byteBuffer));
//读取完要归位
byteBuffer.clear();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
非阻塞
public static void io9() {
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();//阻塞了,不过所有Channel都可以往这里注册
for (SelectionKey key : selector.selectedKeys()){
if (key.isAcceptable()){
SocketChannel socketChannel = serverSocketChannel.accept();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while ( socketChannel.read(byteBuffer)!=-1){
byteBuffer.flip();
socketChannel.write(byteBuffer);
//读取完要归位
byteBuffer.clear();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Okio
- 也是基于插管,单向 Source和Sink
- 支持Buffer
- 可以对Buffer进行操作
- Buffer很好用
- 不强制使用Buffer
用法
需要先导入依赖
implementation 'com.squareup.okio:okio:2.4.3'
public static void io10() {
File file = new File("./a.txt");
// try (Source source=Okio.source(file);){
// Buffer buffer = new Buffer();
// //Buffer 是个工具 ,read是往buffer里写
// //source ->buffer ->read
// source.read(buffer,1024);
// System.out.println(buffer.readUtf8Line());
// //不带buffer 不能整行读
//
// }
try (BufferedSource source = Okio.buffer(Okio.source(file))) {
System.out.println(source.readUtf8Line());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void io11() {
File src = new File("./a.txt");
File dest = new File("./c.txt");
try ( BufferedSource bufferedSource = Okio.buffer(Okio.source(src));
BufferedSink bufferedSink = Okio.buffer(Okio.sink(dest));
){
bufferedSink.writeAll(bufferedSource);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}