Java IO
先了来看一波百度百科
Java的核心库java.io提供了全面的IO接口。包括:文件读写、标准设备输出等。Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。
可以理解为:
从硬盘或者其他设备读取文件到内存这一过程叫做 输入(Input)
从内存输入到硬盘或者其他设备或者文件这一过程叫做 输出 (Output)
分类
按流向分:
输入流: 程序可以从中读取数据的流。
输出流: 程序能向其中写入数据的流。
按数据传输单位分:
字节流: 以字节为单位传输数据的流
字符流: 以字符为单位传输数据的流
超类
字符流又分为输入输出流,其实完全可已根据名字来区分
Reader / Writer 所有字符输入,输出流的抽象类
InputStream / OutputStream 所有字节输入,输出流的抽象类
基本流
按照一个字符进行读取,效率低下,频繁的访问硬盘,每一次读和写的请求都会由OS底层直接处理,这会导致非常低效的问题
FileReader / FileWriter : 读取文件以字符的方式读取, 字符输出流
FilterInputStream / FilterOutputStream : 字节输入 输出流
缓冲流
Buffered(内部自带缓冲区),将会从一个buffer内存区域读取数据,会在buffer空了之后才会被调用(可能一次调用会填充很多数据进buffer)
BufferedReader /BufferedWriter : 字符缓冲输入流 ,输出流
BufferedIntputStream/ BufferedOutputStream: 字节缓冲输入,输出流
转换流
InputStreamReader 可以将输入的字节流转换为字符流,可以指定编码格式,也可以默认 根据系统的编码格式
OutputStreamWrite 是字符流通向字节流的桥梁,可使用指定的 编码 将要写入流中的字符编码成字节,也可以根据系统默认的编码
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator.I1OYHBI4VHCKRVJ\\Desktop\\vue.min.js");
InputStreamReader isr = null;
try {
//以指定编码格式从字节流 转换为字符流
isr = new InputStreamReader(fis, "GBk");
int i;
char cbuf[] = new char[1024];
;
while ((i = isr.read(cbuf))!= -1) {
System.out.println(new String(cbuf, 0, i));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
利用字节流读取文件,通过转换流(字节->字符->字节) 写到硬盘文件
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator.I1OYHBI4VHCKRVJ\\Desktop\\vue.min.js");
InputStreamReader isr = null;
Writer out = null;
try {
//以指定编码格式从字符流 转换为字节流
out = new OutputStreamWriter(new FileOutputStream("c:/abc.txt"), "UTF-8");
//以指定编码格式从字节流 转换为字符流
isr = new InputStreamReader(fis, "GBk");
int i;
char cbuf[] = new char[1024];
;
while ((i = isr.read(cbuf))!= -1) {
System.out.println(new String(cbuf, 0, i));
out.write(new String(cbuf, 0, i));
}
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out !=null) {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印流
PrintStream/PrintWriter
PrintStream
try {
PrintStream ps = new PrintStream(new FileOutputStream("c:/1.txt"),true); //自动刷新
ps.println("xxxxxx");//字符串
ps.println(122.2);//浮点数
ps.println(1122); //打印整数
ps.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PrintWriter
try {
PrintWriter pw=null;
try {
pw = new PrintWriter("c:/abcd.txt","UTF-8"); //指定字符,指定文件
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //自动刷新
pw.println("xxxxxx");//字符串
pw.println(122.2);//浮点数
pw.println(1122); //打印整数
pw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
对象流
ObjectInputStream/ObjectOutputStream 对基本数据和对象进行序列化操作支持。
只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能被ObjectInputStream/ObjectOutputStream所操作!
对象序列化与反序列化 输入输出
ObjectOutputStream oos = null;
ObjectInputStream ois=null;
File file = new File("c:/ObjectInputStream.txt");
//序列化
try {
oos = new ObjectOutputStream(new FileOutputStream(file));
Map<String,String> map = new HashMap<>();
map.put("name", "张三");
oos.writeObject(map);
oos.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(oos!=null) {
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//反序列化
Object obj = null;
try {
ois = new ObjectInputStream(new FileInputStream(file));
HashMap<String, String> hashMap = null;
try {
hashMap = (HashMap<String, String>) ois.readObject();
String string = hashMap.get("name");
System.out.println(string);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(ois!=null) {
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。