一、io流分为字节流和字符流
其继承体系如下
输入流(InputStream/Reader):把数据从其他存储机制读入到当前内存机制当中
输出流(OutputStream/Writer):把内存当中的数据写出到其他存储机制当中
缓冲流(BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter)
数据流(DataInputStream/DataOutputStream):属于字节流
对象流(ObjectInputStream/ObjectOutputStream):属于字节流
注意:能够对对象直接进行读写操作,使用过程中所对应的类全部需要序列化(实现序列化接口)
包装流(缓冲流/数据流/对象流):只能对已有的流进行封装,不能直接关联文件进行操作
序列化:1)需要序列化的类必须实现Serializable接口
2)Serializable接口没有抽象方法,只是标注该对象可以被序列化
3)没有实现Serializable接口类的对象是不能通过对象流传输的
1、字节流(InputStream/OutputStream):读取和写入数据的时候,以字节为最小单元进行读取和写入操作
1)字节输入流(InputStream):我们主要学习了FileInputStream、ObjectInputStream、filterInputStream的子类DataInputStream和BufferedInputStream
(1)FileInputStream(可直接操作文件):
a)单字节读出
package com.test.exercise_6;
import java.io.File;
import java.io.FileInputStream;
public class InputTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("test.txt");// 文件对象
// FileInputStream in = new FileInputStream("test.txt");
FileInputStream in = new FileInputStream(file);// 输入流对象
System.out.println(in.available());// 打印的是流通道中还估计剩余的字节数
/**
* 读取流通道中的一个字节,返回int值,而且每读取一个字节,流通道中会少一个字节
*/
int value = in.read();// 读取一个字节
while (value != -1) {// 判断文件中是否有内容
char c = (char) value;// 强制转换为char
System.out.print(c);// 输出
value = in.read(); // 再读一个字节
}
in.close();// 关闭流
}
}
结果:将文件中的字母读出来了
b)字节读出易错点
package com.test.exercise_6;
import java.io.File;
import java.io.FileInputStream;
public class InputTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("test.txt");// 文件对象
// FileInputStream in = new FileInputStream("test.txt");
FileInputStream in = new FileInputStream(file);// 输入流对象
System.out.println(in.available());// 打印的是流通道中还估计剩余的字节数
// /**
// * 这样一次循环就读取了两次字节,但是只打印了一次
// */
while (in.read() != -1) {
char c = (char) in.read();
System.out.print(c);
}
in.close();// 关闭流
}
}
结果:只读了6个字母而且是每隔一个字母读一次
c)字节数组读出
package com.test.exercise_6;
import java.io.File;
import java.io.FileInputStream;
public class InputTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("test.txt");// 文件对象
// FileInputStream in = new FileInputStream("test.txt");
FileInputStream in = new FileInputStream(file);// 输入流对象
System.out.println(in.available());// 打印的是流通道中还估计剩余的字节数
// /**
// * 但是对于中文就不好了,中文占两个字符,会有字符拆分问题
// */
byte[] bytes = new byte[3];// byte数组建立
int value = in.read(bytes);// 读取一个数组,返回真正读取的字节数
while (value != -1) {
String str = new String(bytes, 0, value);// 字节数组转为字符串,从0到真正读取的字节数
System.out.print(str);// 输出字符串
value = in.read(bytes);
}
in.close();// 关闭流
}
}
结果:出现乱码,也是字节流的弊端
(2)BufferedInputStream
// BufferedInputStream应用实例
try {
FileInputStream fis = new FileInputStream("test.txt");
BufferedInputStream bis = new BufferedInputStream(fis, 256);// 包装流,不可直接操作文件,可设置缓冲区大小
System.out.println(bis.available());
byte[] bytes = new byte[256];
int value = bis.read(bytes);
while (value != -1) {
String str = new String(bytes, 0, value);
System.out.println(str);
value = bis.read(bytes);
}
// fis.close();
bis.close();// 当有文件字节流又有字节缓冲流,关闭流可以选择关闭任意哪个,最好关闭缓冲流
} catch (Exception e) {
e.printStackTrace();
}
(3)DataInputStream
// DataInputStream的应用实例
try {
FileInputStream fis = new FileInputStream("test1.txt");
DataInputStream dis = new DataInputStream(fis);
// System.out.println(dis.readByte());
// System.out.println(dis.readShort());
// System.out.println(dis.readInt());
// System.out.println(dis.readLong());
// System.out.println(dis.readFloat());
// System.out.println(dis.readChar());
dis.skip(21);// 跳过的字节数
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
} catch (Exception e) {
e.printStackTrace();
}
(4)ObjectInputStream
// ObjectInputStream读出
try {
FileInputStream fis = new FileInputStream("test2.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<String> list1 = (ArrayList<String>) ois.readObject();
for (int i = 0; i < list1.size(); i++) {
System.out.println(list1.get(i));
}
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
2)字节输出流(OutputStream):我们主要学习了FileOutputStream、ObjectOutputStream、FilterOutputStream的子类DataOutputStream和BufferedOutputStream
(1)FileOutputStream
a)单字节写入文件
package com.test.exercise_6;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 输出流,写入的文件不存在时会自动创建这个文件,但前提是这个路径要存在
*
* @author lhz
*
*/
public class OutputTest {
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\lhx\\Desktop\\test1.txt");// 文件对象,当该文件不存在时会自动创建
FileOutputStream out = new FileOutputStream(file);// 输出流
out.write(97);// 一个字节写入
out.close();
}
}
结果 :
b)字节数组写入文件
package com.test.exercise_6;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 输出流,写入的文件不存在时会自动创建这个文件,但前提是这个路径要存在
*
* @author lhz
*
*/
public class OutputTest {
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\lhx\\Desktop\\test1.txt");// 文件对象,当该文件不存在时会自动创建
FileOutputStream out = new FileOutputStream(file);// 输出流
//
byte[] bytes = { 97, 98, 99, 100 };// 字节数组
out.write(bytes);
out.close();
}
}
结果:
c)字节写入文件时追加在原文件末尾(默认不追加)
package com.test.exercise_6;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 输出流,写入的文件不存在时会自动创建这个文件,但前提是这个路径要存在
*
* @author lhz
*
*/
public class OutputTest {
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\lhx\\Desktop\\test1.txt");// 文件对象,当该文件不存在时会自动创建
/**
* 输出流,为true则写入的内容会在该文件中内容的末尾追加;为false则将原文件中的内容覆盖,显示的是新写入的内容
*/
FileOutputStream out = new FileOutputStream(file, true);//
out.write(98);// void
out.close();
}
}
结果:
d)字节写入文件以字符串写入
package com.test.exercise_6;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 输出流,写入的文件不存在时会自动创建这个文件,但前提是这个路径要存在
*
* @author lhz
*
*/
public class OutputTest {
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws Exception {
FileOutputStream out = new FileOutputStream(
"C:\\Users\\lhx\\Desktop\\test2.txt");
String str = "谁的浮生乱了谁的流年...";// 字符串
byte[] c = str.getBytes();// 构造字节数组
out.write(c);
out.close();
}
}
结果:
(2)BufferedOutputStream
// BufferedOutputStreame应用实例
// try {
// FileOutputStream fos = new FileOutputStream("test2.txt");
// BufferedOutputStream bos = new BufferedOutputStream(fos);
// String str = "avbhdfskknckczowuei";
// byte[] bytes = str.getBytes();
// bos.write(bytes);
// bos.flush();
// bos.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
try {
FileOutputStream fos = new FileOutputStream("test1.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = { 97, 98, 99 };
bos.write(bytes);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
(3)DataOutputStream
// DataOutputStream的应用实例,是以它自己的协议写的,我们看不懂
try {
FileOutputStream fos = new FileOutputStream("test1.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeByte(97);// 1
dos.writeShort(1);// 2
dos.writeInt(100);// 4
dos.writeLong(1000000001);// 8
dos.writeFloat(1.22f);// 4
dos.writeChar('a');// 2
dos.writeDouble(1.1);// 8
dos.writeBoolean(true);// 1
dos.flush();
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
(4)ObjectOutputStream
// 优化:对象流实现
try {
FileOutputStream fos = new FileOutputStream("test2.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(list);
oos.flush();
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
2、字符流(Reader/Writer):读取和写入数据时,以字符为最小单元进行读取和写入操作,因为每个字符根据编码不同,所占用的字节数不同。每次读取和写入时,以不定长字节个数进行读取和写入
1)Reader:我们主要学习了BufferedReader、InputStreamReader的子类FileReader
(1)FileReader
package com.test.exercise_6;
import java.io.File;
import java.io.FileReader;
public class ReadTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\lhx\\Desktop\\test2.txt");// 文件对象
FileReader reader = new FileReader(file);// 字符流通道
char[] c = new char[256];// 构造一个字符数组
int value = reader.read(c);// 读取,返回int(真正读取的长度),如果到达文件尾,则返回-1
while (value != -1) {
String str = new String(c, 0, value);
System.out.println(str);
value = reader.read(c);
}
reader.close();
}
}
结果:
(2)BufferedReader
// BufferedReader的应用实例
// NO1.字符数组读取
try {
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr);
char[] chars = new char[256];
int value = br.read(chars);
while (value != -1) {
String str = new String(chars, 0, value);
System.out.println(str);
value = br.read(chars);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
// NO2.按行读取
try {
FileReader fr = new FileReader("test4.txt");
BufferedReader br = new BufferedReader(fr);
String str = br.readLine();// 读到文件末尾返回null
while (str != null) {
System.out.println(str);
str = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
2)Writer:我们主要学习了BufferedWriter、OutputStreamWriter的子类FileWriter
(1)FileWriter
package com.test.exercise_6;
import java.io.File;
import java.io.FileWriter;
public class WriteTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\lhx\\Desktop\\test.txt");
FileWriter writer = new FileWriter(file, true);
String str = "谁的浮生乱了谁的流年";
char[] c = str.toCharArray();// 获取字符数组
writer.write(str);
writer.close();
}
}
结果:
(2)BufferedWriter
// BufferedWriter的应用实例
try {
FileWriter fw = new FileWriter("test3.txt");
BufferedWriter bw = new BufferedWriter(fw);
String str = "我吹一曲千蝶纷";
bw.write(str.toCharArray());
bw.flush();
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
3、io拓展:字节流不能直接转化为字符流,但是可以这样转化
package com.test.exercise_6;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class IOExpand {
public static void main(String[] args) {
// 思考:字节流能否转化为字符流?
/**
*
*/
// 输入流
try {
FileInputStream fis = new FileInputStream("test.test");
// 将字节流包装为字符流
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
} catch (Exception e) {
e.printStackTrace();
}
/**
*
*/
// //输出流
try {
FileOutputStream fos = new FileOutputStream("test.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);
} catch (Exception e) {
e.printStackTrace();
}
}
}