io使用场景
当想要将某些数据存储到磁盘内,以便程序关闭、再次运行的时候还可以查到这个数据,这时我们需要用io流将这些数据写出程序写入到本地文件里、或者保存到数据库等等。
iO详解
查看java API文档——java.base——java.io。发现有很多接口、类、方法调用(简单来说就是有点乱七八糟) 张下面这样↓
所以从宏观角度简单分分类,然后分解学习:
io分类
按照读取单位分:
字节流(一次性传入一个字节,8bit)(可以处理任何数据)
字符流(java一个字符16bit)(只能处理字符类型)
按照输出、输入方向分:(字节、字符流都各自不同方向的方法)
输入流(从内存文件、缓存、键盘中读数据)
输出流(将数据写入到内存、缓存、操作台等等)
//字符流:
read
writer
//字节流:
inputStream
outputStream
按照目标节点分:(从哪读,写到哪。就是容器类型不一样,感觉有点对应读写所操作的数据类型,但不完全是,毕竟文件流可以读写int、String等基本类型的数据)
数组ByteArray、CharArray
字符串String、
对象object、
文件file、
Pipe(与其它线程共用的管道中读取数据)、
data、
缓存buffer(避免频繁读写硬盘操作)、
打印数据print(到操作台)、
Sequence(输出输出流序列)、
过滤filter(这个我不太明白)、
字符流、字节流互换等等。
- (我的理解:上面字符、字节的输入输出流是4个父类,具体你要实现从哪读入、读出数据到哪里、读写的操作数据类型、按照什么顺序读入读出……都可以自己个性化重写方法来设计,当然java也自己实例化了以上提及这几种<比较常用>的具体方法,基本每个父类都派生有以上这些子类<但有些也只是inputStream、outputStream有,但是read、writer没有,反过来也是一样的。>,命名一般都是:类型+父类名为后缀)
- API文档里是这样写:
- reader:
- writer:
- inputStream:
- outputStream:
分类基本就是以上这些
有两个优秀博主都给出了思维导图(很清晰der,膜拜一下下)
好像大同小异,互相有一点点补充(后面我会附上大佬们的文章)
io异常
javaAPI文档也给出io异常(很多方法使用的时候都要加上抛exception):
使用方法
//我把那4个父类都演示下用法:
//1.声明一个文件对象
File filename = new File("文件名");
//2.声明一个输入或输出流对象+读出/写入操作 (根据操作的对象或目标节点选择流)
//字节:从文件读出数据给num:
int num = 123;
FileInputStream fileInputStream = new FileInputStream(获取数据的文件对象)
num = fileinputStream.read(); //将读到的数据赋给num
//字节:把数据写入到文件中
FileOutputStream fileOutputStream = new FileOutputStream(写入的文件对象)
fileOutputStream.write(num) //将数据num写入文件内
//字符:从文件读出
FileReader fr = new FileReader("demo.txt");
num = fr.read();
//字符:写入到文件
FileWriter fw = new FileWriter("demo.txt");
fw.write(num);
//3.关闭流操作
fileInputStream.close()
fileOutputStream.close()
fr.close();
fw.close();
//ps:
//1.其他类型的读写类大同小异,但是基本都是这是3个过程
//2.文件读写操作有很多设置,比如说写入的时候要不要覆盖原来的内容、还是接着文件末尾写等等
一些读写机制原理细节
(因为我只暂时练习了file文件流的读写,so只针对与file的stream的分析)
- FileInputStream 读取数据的时候每次读取一个字节,8bit;
- FileInputStream从文件开头开始读取,每次读取完1个字节之后指针位于当前位置不变,因此紧接着再次读取读的是第2个字节,直到读到文件为空为止,读不到数据会返回-1。
- FileOutputStream将数据写入文件每次写一个字节,如果写入的数据类型是大于1个字节的,默认写低八位。
- FileOutputStream每次写数据到文件末尾。
- FileInputStream,所要读取的文件如果实际上不存在会报异常;FileOutputStream要写入的文件如果实际上不存在则会自动在该程序目录下新建一个这样的文件,并把数据写进去。
- 基于以上知识,将多个字节的数据对象写入到文件再读出的时候需要注意顺序。
- 假设读写num(int类型)以下是一个示意图:
练习代码:自己设计将int类型数据写入/写出文件的类
联系的思路:要保证读进去一个int,写出来还是我想要的那个int;读入多个数据的顺序和读出的顺序一致。
//IntIo.java
import java.io.*;
public class IntIO {
private File file;
public IntIO(File file){ //构造函数:传入想要读/写的文件
this.file = file;
}
public void writer(int number) throws IOException { //写操作:写4次,从低字节写起
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(number);
fileOutputStream.write(number>>>8); // >>>是逻辑右移(虽然看起来没啥用)
fileOutputStream.write(number>>>16);
fileOutputStream.write(number>>>24);
System.out.println("写入成功!");
}
public int reader() throws IOException { //读操作:读4次,先读出低字节,不同字节分别取然后调整位置,合并
FileInputStream fileInputStream = new FileInputStream(file);
int num1 = fileInputStream.read();
int num2 = (fileInputStream.read())<<8;
int num3 = (fileInputStream.read())<<16;
int num4 = (fileInputStream.read())<<24;
return (num1+num2+num3+num4);
}
}
//Test.java
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
IntIO intIO = new IntIO(new File("text.txt"));
intIO.writer(1000);
System.out.println(intIO.reader());
}
}
学习文章:大佬博客Java——IO流超详细总结 - 说故事的五公子 - 博客园 ->方法怎么用的代码讲解超级清晰
Java IO流学习总结一:输入输出流_赵彦军-CSDN博客_javaio流 ->逻辑一流,几个流的分类、之间的关系比较全
不太懂filter是啥,虽然这篇↓也没有讲他是干啥用的,但是有代码示例可以看看理解下:
Java_io体系之FilterWriter、FilterReader简介、走进源码及示例——15_Oscar Chen-CSDN博客