Java之IO流必须掌握的知识点
文章目录
IO流的分类
有多种分类方式
- 一种方式是按照流的方向进行分类:
输入流:
以内存为参照物:往内存中去,叫做输入(Input),或者叫做读(Read)输出流:
从内存中出来,叫做输出(Output),或者叫做写(Write) - 另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,称为字节流
。一次读取1个字节,等同于一次读取8个二进制位。这种流什么类型的文件都可以读取。如:文本文件,图片,声音文件,视频文件等
有的流是按照字符的方式读取数据的,称为字符流
。一次读取一个字符,这种流是为了方便读取普通的文本文件而存在的,这种流不能读取:图片、声音、视频等文件,只能读取纯文本文件,连word文件都无法读取
四大IO抽象流
-
java.io.InputStream 字节输入流
-
java.io.OutStream 字节输出流
-
java.io.Reader 字符输入流
-
java.io.Writer 字符输出流
InputStream、OutStream、Reader、Writer 四个都是抽象类
- 所有流都实现了,java.io.Closeable接口,都是可关闭的,每次用完必须关闭,用close()方法关闭
- 所有流都实现 了java.io.Flushable接口,都是可刷新的,都有flush()方法。输出流在最终输出之后要用flush()刷新一下,将流中剩余为输出的数据强行输出。作用:清空流的通道。
注意:在Java中只要类名以Stream结尾的都是字节流,以”Reader/Writer“结尾的都是字符流
java.io包下需要了解的16个流
文件流:
- java.io.FileInputStream
- java.io.FileOutputStream
- java.io.FileReader
- java.io.FileWriter
转换流:(将字节流转换成字符流) - java.io.InputStreamReader
- java.io.OuputStreamWriter
缓冲流: - java.io.BufferedReader
- java.io.BufferedWriter
- java.io.BufferedInputStream
- java.io.BufferedOnputStream
数据流: - java.io.DataInputStream
- java.io.DataOnputStream
对象流: - java.io.ObjectInputStream
- java.io.ObjectOnputStream
标准输出流: - java.io.PrintWriter
- java.io.PrintStream
比较重要的几个IO流的例子
- FileInputStream
读取文件:
package cn.java_io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestFileInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis=null;
try {
//此处采用绝对路径!!!
fis=new FileInputStream("E:\\eclipse-workspace\\a.txt");
int readData=0; //readDate为读取的字节数
//read()方法返回的是读到的字节本身
while((readData=fis.read())!=-1) {
System.out.println(readData); //读到多少输出多少
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}finally {
if(fis!=null) {
fis.close();
}
}
}
}
FileInputStream类的其他常用方法
- int available() : 返回流当中剩余的没有读到的字节数量
- long skip(long n) : 跳过几个字节不读
- FileOutputStream
写:
package cn.java_io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileOutputStream {
public static void main(String[] args) {
FileOutputStream fos=null;
try {
//fos=new FileOutputStream("myfile");//myfile文件不存在时会自动创建
//这种方式谨慎使用,这种方式会先将原文件清空然后再写入
byte[] bytes= {97,98,99,100};
fos=new FileOutputStream("myfile",true);//这种方式则不会将原文件清空,而是在原文件的最后写入
fos.write(bytes);
fos.write(bytes, 0, 2);
fos.flush();//输出流用完用flush()方法刷新
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fos.close();//关闭流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
序列化与反序列化
-
概述:当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常读取。这时候就需要用到序列化与反序列化。把Java对象转换为字节序列的过程称为
对象的序列化
。把字节序列恢复为Java对象的过程称为对象的反序列化
。 -
对象序列化的作用有如下两种:
-
持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
-
网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。
注意:只有实现了Serializable接口的类的对象才能被序列化。
而要进行序列化与反序列化,只需要用到以下两个类: ObjectOutputStream、 ObjectIutputStream,这两个类也是比较重要的。 -
- ObjectOutputStream
package cn.java_io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
** 1、参与序列化与反序列化的对象,必须实现serializable接口
*/
public class TestObjectOutputStream {
public static void main(String[] args) throws Exception, IOException {
//创建Java对象
Student s=new Student(111,"张三",1);
//序列化
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("students"));
//序列化对象
oos.writeObject(s);
//刷新
oos.flush();
//关闭
oos.close();
}
}
这里的studen类必须实现Serializable接口,因为它参与了序列化与反序列化
以下是student类
package cn.java_io;
import java.io.Serializable;
public class Student implements Serializable{
private int age;
private transient String name;
//transient关键字表示游离的,即加了transient后这里的name不参与序列化
private int number;
private static final long serialVersionUID=1L;//手动生成一个序列化版本号
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Student(int age, String name, int number) {
super();
this.age = age;
this.name = name;
this.number = number;
}
public String toString() {
return "Student{"+"age="+age+",name='"+name+
'\''+"number="+number+'}';
}
}
- ObjectInputStream
package cn.java_io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class TestObjectInputStream {
public static void main(String[] args) throws Exception, IOException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("students"));
//开始反序列化,读
Object obj=ois.readObject();
//反序列化回来是一个学生对象,所以会调用学生对象的toString方法
System.out.println(obj);
ois.close();
}
}