IO流结构图(红色为常用类)
1、FileStream
FileInputStream可以从文件中读取字节 FileOutputStream可以把字节写入文件
计算机中所有的指令与数据都是以01二进制形式存在的 即硬盘上不管什么格式的文件都是以01二进制形式存储的
即FileInputStream可以读取任意格式文件中的字节 FileOutputStream可以把字节写入任意格式的文件中
FileInputStream
新建abc.txt文件
ABCDEFGHIJKLMNOPQRSTUVWXYZ
a
基本操作
static void m1() throws IOException {
// 1)在当前程序与要读取的文件之间建立 输入流通道
// 调用 FileInputStream(String name) 构造方法创建流对象,通过构造方法指定要读取哪个文件
FileInputStream fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\abc.txt");
// 2)读取文件中的字节
// int read() 从文件中读取一个字节,并返回读到的字节,如果读到文件末尾返回-1
int read = fis.read();
System.out.println(read + "---" + (char) read);
// int read(byte[] b) 从文件中读取若干字节保存到b数组中,返回读到的字节数量
byte[] bytes = new byte[4]; //定义字节数组作为容器
System.out.println(Arrays.toString(bytes)); //[0, 0, 0, 0]
/*
从文件中读取若干字节保存到bytes数组中,文件中实际上有一个文件指针指向要读取的字节,
在前面read()读取了A这个字节后,文件指针现在就指向A的后面,当前文件中还剩BCDEFG...Z,
bytes字节数组容量是4,会把文件中的BCDE这4个字节读取到bytes数组中,方法返回4表示这一次读取了4个字节
*/
int len = fis.read(bytes);
System.out.println(len); //4
System.out.println(Arrays.toString(bytes)); //[66, 67, 68, 69]
// 3)关闭流通道
fis.close();
}
一次读取一个字节,读取文件中所有字节
static void m2() throws IOException {
// 1)在当前程序与要读取的文件之间建立 输入流通道
FileInputStream fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\abc.txt");
// 2)调用int read() 从文件中读取一个字节,并返回读到的字节,如果读到文件末尾返回-1
int bb = fis.read();
while (bb != -1) {
// 可以对读取的bb这个字节进行处理,因为当前文本文件只有英文字符,可以把读取的字节转换为字符打印
System.out.println(bb + "---" + (char) bb);
// 读取下个字节
bb = fis.read();
}
// 注意:在Windows操作系统中,在文本编辑器中敲回车换行,Windows会插入两个字符‘\r’回车符与‘\n’换行符,
// 回车符的码值是13,换行符的码值是10
// 3)关闭流
fis.close();
}
用 byte[] 数组读取文件
static void m3() throws IOException {
// 1)在当前程序与要读取的文件之间建立 输入流通道
FileInputStream fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\abc.txt");
// 2)调用int read(byte[] b) 从文件中读取若干字节保存到b数组中,返回读到的字节数量,如果读到文件末尾返回-1
byte[] bytes = new byte[102]; // 定义字节数量作为容器,在实际开发中字节数组通常是1024 * 8的容量
int len = fis.read(bytes);
// 当读到的字节数len不是-1,说明没有到文件末尾
while (len != -1) {
//可以对bytes数组中读取的前len个字节进行处理,因为文本文件中只有英文字符,可以把bytes数组中前len个字节转换为字符串打印出来
System.out.println(Arrays.toString(bytes));
System.out.println(new String(bytes, 0, len)); //把bytes数组中从0开始的len个字节转换为字符串
// 继续读取还保存到bytes数组中
len = fis.read(bytes);
}
// 3)关闭流
fis.close();
}
FileOutputStream
把字节写入文件
// 创建字节输入流通道,调用FileOutputStream(String name) 构造方法,通过参数指定要写入的文件
// 如果路径中的某文件夹不存在,抛出异常
// 如果要写入的文件不存在则创建一个新的文件,如果文件已存在则会覆盖文件已有的内容
// FileOutputStream fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt");
// 如果要写入的文件不存在则创建一个新的文件,如果文件已存在则在文件已有的内容后面追加新的内容
FileOutputStream fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt", true);
// 调用 void write(int b) 向文件中写入一个字节,需要由开发人员先把数据转换为字节再写入
fos.write(97);
fos.write(97);
fos.write(97);
fos.write(97);
// 调用void write(byte[] b) 可以把b字节数组中所有的字节写入文件
byte[] bytes = "\nHello动力节点".getBytes(); // 把字符串以当前默认UTF8编码转换为字节数组,在UTF8编码中,一个英文占1字节,一个汉字占3个字节
fos.write(bytes); //把bytes数组中所有的字节都写入文件
// void write(byte[] b, int off, int len) 把b数组中从off开始的len个字节写入文件
fos.write(bytes, 0, 5); // 注意:如果涉及中文,需要把中文字符对应的完整的3个字节都写入文件,否则会出现乱码
// 关闭流
fos.close();
IOException 处理
关闭流放在finally子句中
static void m1() {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\asbc.txt");
int bb = fis.read();
while (bb != -1) {
System.out.println((char) bb);
bb = fis.read();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println(e.getMessage());
} finally {
// 关闭流就是释放系统资源,通常放在finally子句中
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
System.out.println("123");
}
try资源块的应用——自动关闭流
static void m2() {
// 从JDK7开始,增加了try资源块,在try资源块中创建的流会自动关闭
try (
// try关键字后面加一对小括弧,这就是try资源块,在小括弧中建立的流会自动关闭
FileOutputStream fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt")
) {
fos.write(98);
fos.write(98);
fos.write(98);
fos.write(98);
} catch (IOException e) {
throw new RuntimeException(e);
e.printStackTrace();
}
}
2、BufferedStream 缓冲流
BufferedInputStream
static void m1() {
try (
// 先创建FileInputStream输入字节流
FileInputStream fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\abc.txt");
// 再创建BufferedInputStream对fis进行缓冲
BufferedInputStream bis = new BufferedInputStream(fis)
) {
// 使用bis缓冲流从文件中读取数据
int bb = bis.read(); //读取一个字节
while (bb != -1) {
System.out.println((char) bb);
bb = bis.read();
}
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedOutputStream
static void m2() {
// 先创建输出字节流
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
// 先创建输出字节流
fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt");
// 创建BufferedOutputStream对fos进行缓冲
bos = new BufferedOutputStream(fos);
// 向bos的缓冲区写入数据,并没有立即写入文件
bos.write(97);
bos.write(97);
bos.write(97);
// 手动刷新缓冲区
// bos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 一般情况下,关闭资源的顺序与打开顺序相反
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
try资源块简洁语法
static void m3() {
try (
FileOutputStream fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\test.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos)
) {
bos.write(97);
bos.write(97);
bos.write(97);
bos.write(97);
bos.write(97);
bos.write(97);
} catch (IOException e) {
e.printStackTrace();
}
}
3、DataStream 数据流
DataOutputStream
static void writeData() {
try (
// 先创建FileOutputStream输出字节流
FileOutputStream fos = new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\test.txt");
// 创建缓冲流
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 创建数据流
DataOutputStream dos = new DataOutputStream(bos)
) {
// 向文件中写入整数,小数,字符,字符串...
dos.writeInt(12); // 写整数,系统把整数转换为4个字节写入文件
dos.writeDouble(19.31); // 系统把小数转换为8个字节写入文件
dos.writeChar('字'); // 系统把字符转换为2个字节写入文件
dos.writeUTF("98123u9oqfiehbao");
// 直接打开文件显示乱码,该文件需要使用DataInputStream读取
} catch (IOException e) {
e.printStackTrace();
}
}
DataInputStream
static void readData() {
try (
FileInputStream fis = new FileInputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\test.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis)
) {
// 读取的顺序要与写入的顺序一致
int i = dis.readInt();
double v = dis.readDouble();
String s = dis.readUTF();
System.out.println(i);
System.out.println(v);
System.out.println(s);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
4、PrintStream 打印流
// 创建打印流
// PrintStream ps = new PrintStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt");
// 底层会根据文件路径创建FileOutputStream流对象,虽然构造方法可以直接指定文件,但是不是节点流,是处理流
PrintStream ps = new PrintStream(new FileOutputStream("D:\\动力节点\\idea_code\\javaSE\\day10\\src\\file\\def.txt", true));
ps.print("print方法打印完不换行,");
ps.println("pringln打印完后会换行");
System.out.println("System类中的静态变量out就是PrintStream打印字节流,System.out代表系统的标准输出设备,即显示器");
try {
byte[] bytes = "Hello动力节点".getBytes("kkk");
} catch (UnsupportedEncodingException e) {
// e.printStackTrace(); //捕获异常打印到屏幕上
e.printStackTrace(ps); //把异常信息打印到ps流中
}