IO
一.IO是什么?
java io是inputstream和outputStream的总称,其实就是java输入和输出的总称.
如果换我们来设计的话,有两个问题需要考虑:
第一从哪里读写.
第二读写出来的结果是什么类型.
所以解决第一个问题,我们定义了统一的接口,从不同地方读取,我们就是这个接口的不同实现;
解决第二个问题,我们设置了不同的接口,如流式读取,我们的顶层接口为inputStream/outputStream,而字符型顶层接口为reader和writer.
二.IO的分类
IO的分类方式有很多种,我们有以下几种常用分类方式:
1.从读取还是写出可以分为输入流和输出流.
输入:
- FileInputStream 文件输入流
- ByteArrayInputStream 字节数组输入流
- ObjectInputStream 对象输入流
- FileReader 文件输入reader
- …
输出:
- FileOutputStream 文件输出流
- ByteArrayOutputStream 字节数组输出流
- ObjectOutputStream 对象输出流
- FileWriter 文件写writer
- …
2.从来源分类
从来源分类,可以将IO分为以下几种:
- 本地IO(本地操作,如读取文件等)
- 网络IO(从socket中读取,写入数据)
3.从操作对象分类
- 文件IO
读取文件,写入文件的操作类,文件包括txt.jpg,视频文件等等文件都可以.
/**
* 文件读取
* @throws Exception
*/
@Test
public void testFileBio() throws Exception {
long startTime = System.currentTimeMillis();
//获取输入输出流
FileInputStream inputStream = new FileInputStream("D:\\BaiduNetdiskDownload\\1.zip");
FileOutputStream outputStream = new FileOutputStream("D:\\BaiduNetdiskDownload\\2.zip");
byte[] bytes = new byte[1024];
//从1.zip中读取,写入2.zip文件
while(inputStream.read(bytes) != -1){
outputStream.write(bytes);
}
long endTime = System.currentTimeMillis();
System.out.println("复制本文件花费时间:" + (endTime - startTime));
}
- 字符IO
以一个一个的字符操作文件.
/**
* 字符IO
* @throws IOException
*/
@Test
public void test() throws IOException {
FileReader fileReader = new FileReader("2.txt");
FileWriter fileWriter = new FileWriter("3.txt");
char[] chars = new char[1024];
while (fileReader.read(chars) != -1){
fileWriter.write(chars);
}
fileReader.close();
fileWriter.close();
System.out.println("复制完毕");
}
- 字节IO
/**
* byteArrayInputstream
* 作用:将内存中的数据转化成字节数组流的形式,或者将字节数组流转换成内存中的其他数据形式.
*/
@Test
public void test() throws IOException {
//创建流对象,将我爱你这三个字转换字节流.
ByteArrayInputStream inputStream = new ByteArrayInputStream("我爱你".getBytes());
//创一个指定大小的byteArray.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(12);
byte[] bytes = new byte[12];
while(inputStream.read(bytes) != -1){
outputStream.write(bytes);
}
//得到字节数组
byte[] bytes1 = outputStream.toByteArray();
for (int i = 0; i < bytes1.length; i++) {
byte b = bytes1[i];
System.out.print(b);
}
}
- 对象IO #这个就是对象的额序列化于反序列化
(1)对象 <=>文件
/**
* 将对象写入文件中,并且从文件中读取数据
* @throws Exception
*/
@Test
public void testObjectIo() throws Exception {
//将对象写入文件中,也就是序列化对象
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("1.txt"));
Person person = new Person();
person.setName("张三");
person.setAge(18);
outputStream.writeObject(person);
//从文件中读取对象,反序列化对象
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("1.txt"));
Person person1 = (Person) inputStream.readObject();
System.out.println(person1);
}
(2)对象 <=>网络
/**
* 这是模拟客户端
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket socket = new Socket("127.0.0.1",8088);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Person person = new Person();
person.setName("李四");
person.setAge(20);
outputStream.writeObject(person);
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
Object o = inputStream.readObject();
System.out.println(o);
}
/**
* 这是模拟的服务端
* @throws Exception
*/
@Test
public void server() throws Exception {
ServerSocket serverSocket = new ServerSocket(8088);
Socket socket = serverSocket.accept();
//将对象写入socket中,也就是序列化对象
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Person person = new Person();
person.setName("张三");
person.setAge(18);
outputStream.writeObject(person);
//从socket中读取对象,反序列化对象
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
Person person1 = (Person) inputStream.readObject();
System.out.println(person1);
}
- 缓冲区IO(bufferInputstream/bufferOutputstream)
/**
* 这是缓冲区IO流
* @throws Exception
*/
@Test
public void bufferTest() throws Exception {
BufferedInputStream inputStream = new BufferedInputStream(new ByteArrayInputStream("我爱你".getBytes()),1024);
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("4.txt"));
byte[] bytes = new byte[12];
while(inputStream.read(bytes) != -1){
outputStream.write(bytes);
}
}
4.从是否同步
从是否同步来分类,可以分为BIO(阻塞io)和NIO(非阻塞io).
()
未完待续
具体可参考:
文章一:
https://www.zhihu.com/question/29005375
文章2:
https://www.toutiao.com/i6908238524617785863/
linux的5中io模型中,其中最受欢迎的是多路复用IO;这也是为什么该组件速度快的原因之一.具体应用场景有:
java中的NIO
nginx的事件模型
redis的文件模型
http2.0同样也采用的是多路复用IO