流的分类
按操作数据单位分:字节流(二进制文件),字符流(文本文件)
按流向分:输入流,输出流
按流的角色分:节点流,处理流(包装流)
以下是部分IO流所涉及的类的继承关系:
节点流与处理流
节点流:
是底层流 / 低级流,它直接与数据相联系。
处理流:
也叫包装流,对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相联系,不仅可以消除不同节点流的使用差别,还提供了简便的方法来完成数据的输入与输出。
处理流的优点:
- 性能提高:主要以增加缓冲的方式来提高数据输入输出的效率
- 操作便捷:处理流提供了一系列便捷的方法来一次性输入输出大批量的数据,使用时更加方便灵活
创建文件方式
常用的两种创建文件方式、创建目录的方式、获取文件基本信息的方法:
import java.io.File;
import java.io.IOException;
public class GetFileInfo {
public static void main(String[] args) {
create1();
// create2();
File file = new File("E:\\file1.txt");
System.out.println("文件名字:" + file.getName());
System.out.println("文件绝对路径:" + file.getAbsolutePath());
System.out.println("文件父目录:" + file.getParent());
System.out.println("文件字节大小:" + file.length());
System.out.println("文件是否存在:" + file.exists());
System.out.println("是不是一个文件:" + file.isFile());
System.out.println("是不是一个目录:" + file.isDirectory());
}
//创建文件方法1
public static void create1() {
String filePath = "E:\\file1.txt";
File file = new File(filePath);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("文件创建成功。");
}
//创建文件方法2
public static void create2() {
String parentFile = "E:\\";
String name = "file2.txt";
File file = new File(parentFile, name);
try {
file.createNewFile();
System.out.println("文件创建成功。");
} catch (IOException e) {
e.printStackTrace();
}
}
//创建目录方法
public static void createDirectory() {
String filePath = "E:\\dir1";
File file = new File(filePath);
file.mkdirs();
System.out.println("目录创建成功。");
}
}
字节流
InputStream – 输入流
InputStream 是一个抽象类,是所有字节 输入类(流)的超类
FileInputStream – 文件字节输入流
import java.io.FileInputStream;
public class FileInputStream01 {
public static void main(String[] args) throws Exception{
String filePath = "E:\\a.txt";
FileInputStream fileInputStream = new FileInputStream(filePath);
int readData = 0;
while ((readData = fileInputStream.read()) != -1){
System.out.print((char)readData);//转成char显示
}
fileInputStream.close();
}
}
BufferedInputStream – 缓冲字节输入流
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class BufferedInputStream01 {
public static void main(String[] args) throws Exception{
String filePath = "e:\\a1.txt";
int readData = 0;
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
while ((readData = bufferedInputStream.read()) != -1){
System.out.print((char)readData);//转成char显示
}
bufferedInputStream.close();
}
}
ObjectInputStream – 对象字节输入流
序列化与反序列化:
序列化,就是在保存数据时,同时保存
数据的值
和数据类型
。
反序列化,就是在恢复数据时,同时恢复数据的值
和数据类型
。
条件:
需要序列化的对象必须是实现了Serializable
或者Externalizable
接口的类(可序列化的类)才行。
平时一般是去实现Serializable
接口,它是一个标记接口,没有需要实现的方法,而Externalizable
接口有需要实现的方法,使用时相对繁琐,而且它也是继承了Serializable
接口的。
使用时的注意事项与细节说明:
1、数据的读与写的顺序要一致
2、序列化与反序列化的对象需要实现Serializable
接口
3、序列化的类中建议添加 “ private static final long serialVersionUID = 1L;”属性语句,这样能提高版本的兼容性
4、序列化对象时,默认将除了static 或 transient 修饰的
成员全部序列化
5、序列化对象时,其对象所属类里面的属性也需要时2实现了Serializable
接口的
6、序列化具有可继承性,也就是某类已经实现了序列化,则它的所有子类也默认实现了序列化
import java.io.*;
public class ObjectInputStream01 {
public static void main(String[] args) throws Exception {
String filePath = "e:\\data.dat";//指定需反序列化的文件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
//2. 否则会出现异常
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
ois.close();
System.out.println("反序列化完成");
}
}
OutputStream – 输出流
OutputStream 是一个抽象类,是所有字节 输出类(流)的超类
FileOutputStream – 文件字节输出流
import org.junit.Test;
import java.io.FileOutputStream;
public class FileOutputStream01 {
public static void main(String[] args) {
}
@Test
public void writeFile() throws Exception {
String filePath = "E:\\a.txt";
FileOutputStream fileoutputStream = null;
//new FileOutputStream(filePath)覆盖方式,覆盖原有内容
//new FileOutputStream(filePath,true)追加方式,从原有内容最后开始写入
fileoutputStream = new FileOutputStream(filePath, true);
String str = "hello,world!";
//str.getBytes()把字符串转换为字节数组
fileoutputStream.write(str.getBytes());
fileoutputStream.close();
}
}
BufferedOutputStream – 缓冲字节输出流
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
public class BufferedOutputStream01 {
public static void main(String[] args) throws Exception{
String filePath = "e:\\a1.txt";
String str = "hello,world!";
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
bufferedOutputStream.write(str.getBytes());
bufferedOutputStream.close();
}
}
ObjectOutputStream – 对象字节输出流
import java.io.*;
public class ObjectOutStream01 {
public static void main(String[] args) throws Exception {
//序列化后,保存的文件格式不是存文本,而是按照他自己的格式来保存
String filePath = "e:\\data.dat";//序列化数据到 e:\data.dat
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeInt(100);// int -> Integer (实现了 Serializable)
oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
oos.writeChar('a');// char -> Character (实现了 Serializable)
oos.writeDouble(11.1);// double -> Double (实现了 Serializable)
oos.writeUTF("你好!");//String
oos.close();
System.out.println("序列化结束。");
}
}
PrintStream
System.in :标准输入,是InputStream类型,默认设备为 键盘
System.out :标准输出,是PrintStream类型,默认设备为 显示器
import java.io.IOException;
import java.io.PrintStream;
public class PrintStream01 {
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
//System.out -> PrintStream类型
//在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
out.print("hi!");
//因为print底层使用的是write , 所以我们可以直接调用write进行打印/输出
out.write("你好01。".getBytes());
out.close();
//我们可以去修改打印流输出的位置/设备,如:
//1. 输出修改成到 "e:\\a.txt"
//2. "你好02." 就会输出到 e:\a.txt
PrintStream ps = new PrintStream("e:\\a.txt");
System.setOut(ps);
System.out.println("你好02.");
}
}
字符流
Reader – 输入流
Reader 是一个抽象类,是所有字符 输入类(流)的超类
FileReader – 文件字符输入流
import org.junit.Test;
import java.io.FileReader;
public class FileReader01 {
public static void main(String[] args) {
}
//单个字符读取文件
@Test
public void readFile01() throws Exception {
String filePath = "e:\\a1.txt";
//1. 创建FileReader对象
FileReader fileReader = new FileReader(filePath);
int data = 0;
//循环读取 使用read, 单个字符读取
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
fileReader.close();
}
//字符数组读取文件
@Test
public void readFile02() throws Exception {
String filePath = "e:\\a1.txt";
//1. 创建FileReader对象
FileReader fileReader = new FileReader(filePath);
int readLen = 0;
char[] buf = new char[8];
//循环读取 使用read(buf), 返回的是实际读取到的字符数
//如果返回-1, 说明到文件结束
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));
}
fileReader.close();
}
}
BufferedReader – 缓冲字符输入流
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReader01 {
public static void main(String[] args) throws Exception {
String filePath = "e:\\a1.txt";
//创建bufferedReader
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
String line; //获取读取到的字符串
//1. bufferedReader.readLine() 是按行读取文件
//2. 当返回null 时,表示文件读取完毕
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
}
InputStreamReader – 转换流
转换流
,完成字节流向字符流的转换。
在处理纯文本文件时,使用字符流效率更高,这时就可以使用转换流将字节流转换为字符流使用,并且可以在使用时指定需要的编码格式(比如:UTF-8,GBK 等),有效解决中文乱码问题
InputStreamReader 是 Reader的子类,可以将 InputStream的子类(字节流)包装(或叫转换)成为 Reader的子类(字符流)
import java.io.*;
public class InputStreamReader01 {
public static void main(String[] args) throws Exception {
String filePath = "e:\\a.txt";
String charSet = "gbk";
//1. 把 FileInputStream 转成 InputStreamReader后传入BufferedReader
//2. 指定编码 gbk
//方式1,分开写
//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), charSet);
//BufferedReader br = new BufferedReader(isr);
//方式2,连起来写
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charSet));
// BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//按默认编码方式读取
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
System.out.println("按照 " + charSet + " 编码方式读取文件成功。");
}
}
Writer – 输出流
Writer 是一个抽象类,是所有字符 输出类(流)的超类
FileWriter – 文件字符输出流
注意:
FileWriter 使用完后,必须 close() 关闭 或者 flush() 刷新 否则写入不到相应的文件中去
import java.io.FileWriter;
public class FileWriter01 {
public static void main(String[] args) throws Exception {
String filePath = "e:\\a2.txt";
//创建FileWriter对象
FileWriter fileWriter = new FileWriter(filePath);
//write(int):写入单个字符
fileWriter.write('A');
//write(char[]):写入指定数组
char[] chars = {'a', 'b', 'c'};
fileWriter.write(chars);
//write(string):写入整个字符串
fileWriter.write("很高兴见到你。");
fileWriter.write("你好!");
//write(string,off,len):写入字符串的指定部分
fileWriter.write("很高兴见到你。", 1, 2);
fileWriter.close();//必须有关闭操作,否则无法把数据写入到文件中
System.out.println("程序结束...");
}
}
BufferedWriter – 缓冲字符输出流
它是一种处理流(也叫包装流),可以把Writer的所有子类包装在它里面,为程序提供更为强大的读写功能,在关流时,也只需要关闭外层流即可,它的内部会自动关闭内层的流
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\a4.txt";
//1. new FileWriter(filePath, true) 表示以追加的方式写入
//2. new FileWriter(filePath) , 表示以覆盖的方式写入
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
bufferedWriter.write("内容1");
bufferedWriter.newLine();
bufferedWriter.write("内容2");
bufferedWriter.newLine();
bufferedWriter.write("内容3");
bufferedWriter.newLine();
bufferedWriter.write("内容4");
bufferedWriter.newLine();
bufferedWriter.write("内容5");
bufferedWriter.newLine();
//......
bufferedWriter.close();
}
}
OutputStreamWriter – 转换流
import java.io.*;
public class OutputStreamWriter01 {
public static void main(String[] args) throws Exception {
String filePath = "e:\\a.txt";
String charSet = "gbk";
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath),charSet));
// BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath)));//按默认编码方式保存
bw.write("hi!");
bw.newLine();
bw.write("你好!");
bw.newLine();
bw.close();
System.out.println("按照 " + charSet + " 编码方式保存文件成功。");
}
}
PrintWriter
import java.io.FileWriter;
import java.io.PrintWriter;
public class PrintWriter01 {
public static void main(String[] args) throws Exception{
String filePath = "e:\\a.txt";
//数据输出到文件 e:\a.txt 中
PrintWriter printWriter = new PrintWriter(new FileWriter(filePath));
//数据输出到控制台中,System.out -> 标准输出(控制台显示屏)
// PrintWriter printWriter = new PrintWriter(System.out);
printWriter.write("你好。");
printWriter.close();
}
}