文章目录
IO概述
计算机的核心(CPU和内存),与其它设备之间数据转移的过程就是IO。比如数据从磁盘读入到内存,或内存的数据写回到磁盘,都是IO操作。在计算机的世界里,这就是IO的本质
IO = Input + Out
最简单的例子,CPU将内存中的数据换出到磁盘,就叫Out,反之,从磁盘将数据换入到内存,叫Input
IO流在java中-以输入输出角度分类
- 输入流
- 输出流
IO流在java中-以数据形式的角度分类
- 字符流
- 字节流
字符流以我们平常用的文本文件为代表,字节流以我们平时用的mp3、视频、图片等文件为代表,以二进制文件形式传输
IO流的使用必须关闭
流对象占用了系统资源,比如:文件句柄、端口、数据库连接等。无法简单从JVM堆中自动回收,故使用时需要手动关闭
字符输出流Writer
Writer类是一个抽象类,我们使用它的孙子类FileWriter来做演示,它支持将字符流写出到某个文件中
- 基本构造器:
File file = new File("test.txt") ;
Writer writer = null ;
try {
writer = new FileWriter(file) ;
//or
writer = new FileWriter("text1.txt") ;
//覆盖模式 非追加
writer = new FileWriter("text1.txt",true) ;
} catch (IOException e) {
e.printStackTrace();
}finally {
if (writer!= null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 写入方式
try {
writer = new FileWriter("text1.txt",false) ;
//字符数组方式写入
char[] c= {'a','b','c'} ;
writer.write(c);
writer.write(c,1,1);//从第几个下标,以几个长度写入
//字符串形式写入
writer.write("helloword\r\n"); //\r\n表示换行,如果linux下变成,直接\n即可
//分批写入
for (int i = 0 ; i<100 ; i++) {
writer.write("helloword\r\n");
if (i == 100)
//将缓冲区数据全部打到输出流
writer.flush();
}
我们一般用第三种方法进行文件字符流写
FileReader字符输入流
Reader reader = null ;
reader = new FileReader("text1.txt") ;
单字符读取:
int c = reader.read() ;
System.out.println( (char)c );
- 单字符读取读的过程像指针,一去不复返
- 返回值:读到的字符个数
- 最后读出来是个**-1**代表无内容
- 效率低下,一般不用
以数组为单位读:
/*按数组组读取:读入数组*/
char[] cs = new char[5];
int len = reader.read(cs) ; //读取到多少个有效数据
System.out.println(Arrays.toString(cs));
System.out.println(len);
结果:hello
5
- 若读取后的剩余内容少于数组长度,会覆盖数组前节相应长度的内容
- 无数据是-1
批量读取:
char[] cs = new char[5];
while ((c = reader.read(cs))!=-1){ //= -1即读取完毕
String str = new String(cs,0,c) ;//0代表起始位置,c代表读取到的长度
System.out.println(str);
}
BufferedReader/BufferedWriter
带着缓冲区的字符读写
- 一次IO换入换出代表CPU得暂停当前线程,等待数据换入完毕或换出,这个时候如果切换线程则有线程上下文的代价,如果不切换则浪费CPU资源,故IO次数当然是越少越好
基本构造:
BufferedReader br = null ;
BufferedWriter bw = null ;
br = new BufferedReader(reader) ;
bw = new BufferedWriter(writer) ;
读取数据:
String str = null;
//BufferedReader读结束的标志是返回的是null
while ((str = br.readLine()) != null){
System.out.println(str);
}
写出数据:
BufferedWriter的写方法是按字符串换出的,如需要换行,在写入方法的后面添加newLine(换行方法)
并且需要分批flush
bw.write("hello1");
bw.newLine(); //换行
bw.write("hello2");
//须加个flush
//上面的输出会被暂时放在缓冲区中
//flush的时候换出到磁盘文件,减少IO次数
writer.flush();
字节流和字符流的区别
每次读写的字节数不同;
字符流是按块读写,字节流是以字节为单位读写;
字符流带有缓存,字节流没有。
字符流和字节流,一个属性范围小,一个属性范围大,字符流只能是字符这一种类型,但是字节流中可以是字符,可以是二进制文件,可以是音频,可以是各种各样的类型,只要符合字节形式存储的都可以接字节流,而字符流只能接字符
字节IO流对象
OutputStream out =null ;
InputStream in = null ;
//文件输入流
in = new FileInputStream("testIO2.txt") ;
//文件输出流
out = new FileOutputStream(new File("testIO2.txt")) ;
//文件输出流 追加模式
out1 = new FileOutputStream("testIO2.txt",false) ;
写入
一般以数组形式进行写入
byte[] bs = {97,99,103,111} ; //展示的是asc码
out.write(bs);
读取
byte[] bs1 = new byte[2] ;
int len = -1 ;//-1代表读不到东西了
while ((len = in.read(bs1)) != -1){
String str = new String(bs1,0,len) ;
OutputStreamWriter/InputStreamWriter
OutputStreamWriter是从字符流到字节流的桥接:写入它的字符使用指定的字节编码为字节集
此部分主要考虑编码问题,比如我们需要控制输入与输出的编码,如控制流以GBK编码写入,以GBK编码读取(展示)
OutputStreamWriter ow = null;
InputStreamReader ir = null ;
/*参数为out/inputstream对象*/
ow = new OutputStreamWriter(new FileOutputStream("testIO2.txt"),"utf-8")
ir = new InputStreamReader(new FileInputStream("testIO2.txt"),"utf-8") ;
对象流
由于jvm的机制,对象在程序运行结束后会被回收,如果我们需要讲对象持久化存储,可以考虑把对象以流的形式存储在硬盘上或者数据库中,这个过程就是序列化流
- 对象输出流:ObjectOutputStream(将Java 对象的基本数据类型和图形写入 OutputStream)
- 对象输入流:ObjectInputStream (对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化(提取回来))
- 被序列化的实体类需实现Serializable接口
Student student = new Student(101,"武松") ;
Student student1 = new Student(102,"刘备") ;
/*多个对象需要以集合的方式序列化*/
List<Student> sList = new ArrayList<>() ;
sList.add(student);
sList.add(student1);
/*对象流创建*/
ObjectOutputStream out = null ;
ObjectInputStream in = null ;
out = new ObjectOutputStream(new FileOutputStream("testIO2.txt")) ;
in = new ObjectInputStream(new FileInputStream("testIO2.txt")) ;
序列化:
out.writeObject(sList); //结果(对象数据)是不支持读懂的,反序列化才行
out.flush(); //对象流需要刷新
反序列化
Object o = in.readObject();
List<Student> lists = (List<Student>)o ;
System.out.println(lists);
/*结果
*[Student{sno=101, name='武松', books=[]}, Student{sno=102, name='刘备', books=[]}]
*/