本文已参与[新人创作礼]活动,一起开启掘金创作之路.
本博客由该视频整理而得:视频链接
Io流的分类
- 按照流的方向分为输入流和输出流: 以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read). 从内存中出来,叫做输出(output)。或者叫做写(write).
- 按照读取数据方式不同分为字节流和字符流: 字节流是按照字节的方式读取数据,一次读取1个字节。这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音,视频…… 字符流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。
流的四大家族
- java io流这块有四大家族: java.io.Inputstream字节输入流 java.io.Outputstream字节输出流 java.io.Reader字符输入流 java.io.Writer字符输出流
- 在java中只要"类名"以stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流
- 四大家族的首领是InputStream、OutputStream、Reader、Writer,它们都是抽象类。
close和flush
- 所有的流都实现了:java .io.closeable接口,都是可关闭的,都有close()方法。 流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
- 所有的输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush()方法。养成一个好习惯,输出流在最终输出之后,一定要记得flush刷新一下。 这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道. 如果没有flush可能会导致丢失数据。
常用的流
- 文件专属:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
- 转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
- 缓冲流专属
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
- 数据流专属:
java.io.DataInputStream
java.io.DataOutputStream
- 标准输出流:
java.io.PrintWriter
java.io.PrintStream
- 对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream
FileInputStream
一个简单的使用示例:
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("文件路径");
byte[] bytes = new byte[4];
int readCount = 0;
while ((readCount = fis.read(bytes)) != -1) {
// 读到多少个字节输出多少个字节
System.out.println(new String(bytes, 0, readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 防止NullPointException
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileInputStream的常用方法
int available():返回流当中剩余的没有读到的字节数量
long skip(long n):跳过几个字节不读。
FileOutputStream
一个简单的示例:
public static void main(String[] args) {
FileOutputStream fos = null;
try {
// 以追加的方式写入,不清空原文件
fos = new FileOutputStream("文件路径", true);
// 清空原文件后写入
fos = new FileOutputStream("文件路径");
byte[] bytes = { 97, 99, 101 };
// 将bytes数组全部写出
fos.write(bytes);
// 将bytes数组的一部分写出
fos.write(bytes, 0, 2);
// 输出流关闭之前一定要flush
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 防止NullPointException
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader、FileWriter
使用方法与FileInputStream、FileOutputStream类似
Buffered类、转换流类示例
public static void main(String[] args) {
BufferedReader br = null;
try {
// 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
// 外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
br = new BufferedReader(new InputStreamReader(new FileInputStream("文件路径")));
// 读取文件
String s = null;
while ((s = br.readLine()) != null) {
// 注意上面readLine方法读到的s不包括换行符
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭流,这里判断不为null是为了防止空指针异常
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
改变标准输出流的输出方向
可用于日志文件的记录
public static void main(String[] args) {
// 标准输出流不再指向控制台,而是指向该文件
try {
System.setOut(new PrintStream(new FileOutputStream("文件路径")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 之后再调用标准输出的时候,会输出到上面指定的文件中
System.out.println();
}