博主:_LJaXi
专栏: Java | 从跨平台到跨行业
开发工具:IntelliJ IDEA Community Edition 2022.3.3
Java IO流
- 中秋特供啦 🥮
- Java Io 🍔
- 什么是流
- 流的分类
- 文件字节输入流
- 1. 条件循环解决
- 1 (2) 读取特性
- 2. 数组存储解决
- 文件字节输出流
- 输出流构造方法
- 字节流复制文件
- 字节缓冲流
- BufferedInputStream
- BufferedInputStream 自定义读取部分数据
- BufferedOutputStream
- 对象流
- Student 类
- ObjectOutStream
- ObjectInputSteam
- 序列化和反序列化注意点
中秋特供啦 🥮
提前祝大家 中秋 | 国庆 快乐 🥮🥮🥮
Java Io 🍔
什么是流
I: Input |
输入
O: Output |
输出
流的分类
- 按照数据的流向
- 输入流:读数据
- 输出流:写数据
- 按照数据类型来分
- 字节流
- 字节输入流
- 字节输出流
- 字符流
- 字符输入流
- 字符输出流
输入流
,输出流
字节流
,字符流
文件字节输入流
FileInputStream
package FileInput;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Author: _LJaXi
* @author ASUS
*/
class FileInput {
public static void main(String[] args) throws IOException {
try {
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 一次读取多个字节,存到数组中
// 创建一个长度为3的数组 / 字节类型
byte[] buf = new byte[3];
int count = 0;
// 条件判断循环
while ((count = fis.read(buf)) != -1) {
System.out.print(new String(buf,0,count));
}
// 3. 关闭
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
1. 条件循环解决
package main.java.com.mycode;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Author: _LJaXi
* @author ASUS
*/
class MyIo {
public static void main(String[] args) throws IOException {
try {
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 读取
System.out.println(fis.read());
int data = 0;
// 循环打印字节
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
// 3. 关闭
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
1 (2) 读取特性
package main.java.com.mycode;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Author: _LJaXi
* @author ASUS
*/
class MyIo {
public static void main(String[] args) throws IOException {
try {
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 一次读取多个字节,存到数组中
// 创建一个长度为3的数组 / 字节类型
byte[] buf = new byte[3];
// 返回实例读取的个数
int count = fis.read(buf);
// 打印字符串 buf
System.out.println(new String(buf));
System.out.println(count);
// 多次读取
int count2 = fis.read(buf);
System.out.println(new String(buf));
System.out.println(count2);
int count3 = fis.read(buf);
System.out.println(new String(buf));
System.out.println(count3);
// 若文件内字符太短,可能会出现读取数组you多余元素问题,那是你的上次buf数组没有清空导致的
// 可以使用
// System.out.println(new String(buf, index(索引), count3)); 来清理多余的元素
// new String(buf)参数:
// 1. param1 是一个字节数组,用于构建新的字符串对象
// 2. param2 是偏移量(offset),表示从 param1 的索引为 param2 的位置开始构建字符串
// 3. param3 是长度(length),表示构建字符串的长度
// 3. 关闭
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
2. 数组存储解决
package main.java.com.mycode;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Author: _LJaXi
* @author ASUS
*/
class MyIo {
public static void main(String[] args) throws IOException {
try {
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 一次读取多个字节,存到数组中
// 创建一个长度为3的数组 / 字节类型
byte[] buf = new byte[3];
int count = 0;
// 条件判断循环
while ((count = fis.read(buf)) != -1) {
System.out.print(new String(buf,0,count));
}
// 3. 关闭
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
文件字节输出流
FileOutputStream
package main.java.com.mycode;
import java.io.FileOutputStream;
/**
* Author: _LJaXi
* @author ASUS
*/
public class FileOutput {
public static void main (String[] args) throws Exception {
// 1. 创建文件字节输出流对象
// 若不想覆盖原本内容,将构造方法append,设置为true
FileOutputStream fos = new FileOutputStream("d://aaa.txt", true);
// 2. 写入文件
// fos.write(97);
// fos.write('b');
// fos.write('c');
String str = "helloworld";
// 获取字符串所对应的字节数组
fos.write(str.getBytes());
// 3. 关闭
fos.close();
System.out.println("执行完毕");
}
}
输出流构造方法
// 某个构造方法有个形参 append,这个构造方法的 append 若为true 表明不覆盖原本内容
public FileOutputStream(String name, boolean append)
throws FileNotFoundException
{
this(name != null ? new File(name) : null, append);
}
字节流复制文件
package CopyFile;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 使用文件字节流实现文件的复制
* */
public class CopyFile {
public static void main(String[] args) throws IOException {
// 1. 先用文件字节输入流读到内存中
FileInputStream fis = new FileInputStream("C:\\Users\\ASUS\\Desktop\\凌波.png");
// 2. 再用一个文件字节输出流写入到硬盘
FileOutputStream fos = new FileOutputStream("C:\\Users\\ASUS\\Desktop\\凌波丽.jpg");
// 3. 一边读 一边写
byte[] buf = new byte[1024];
int count = 0;
while((count=fis.read(buf)) != -1) {
fos.write(buf,0,count);
}
// 4. 关闭流
fis.close();
fos.close();
System.out.print("复制完毕");
}
}
字节缓冲流
BufferedInputStream
/Buffered0utputStream
提高IO效率,减少访问磁盘的次数;
数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close;
BufferedInputStream
package Buffered;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
/*
* 使用字节缓冲流读取
* BufferedInputStream
* @Tip 我想和 符韬_(pinegg) 一起玩
* */
public class BufferedStream {
public static void main(String[] args) throws IOException {
// 1. 创建BufferedInputStream
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 增强底层流
BufferedInputStream bis = new BufferedInputStream(fis);
// 2. 读取 bis 读文件会放在缓冲区,提高效率
int count = 0;
// bis.read() 并不是读一个字节,先把一部分数据读到bis缓冲区内,调用已经读了8k了
// private static int DEFAULT_BUFFER_SIZE = 8192;
while ((count=bis.read()) != -1) {
System.out.print((char) count);
}
// 3. 关闭
bis.close(); // 缓冲流close之后, 会自动帮你关闭输入流 fis.close()
}
}
BufferedInputStream 自定义读取部分数据
package Buffered;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
/*
* 使用字节缓冲流读取
* BufferedInputStream
* @author 符韬是谁?
* */
public class BufferedStream {
public static void main(String[] args) throws IOException {
// 1. 创建BufferedInputStream
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
// 增强底层流
BufferedInputStream bis = new BufferedInputStream(fis);
// 2. 读取 bis 读文件会放在缓冲区,提高效率
int count = 0;
// bis.read() 并不是读一个字节,先把一部分数据读到bis缓冲区内,调用已经读了8k了
// private static int DEFAULT_BUFFER_SIZE = 8192;
// 当然你也可以自己定义把一部分数据读取到缓冲区, 下方注释写法
byte[] buf = new byte[6000];
while ((count=bis.read(buf)) != -1) {
System.out.print(new String(buf, 0, count));
}
// 3. 关闭
bis.close(); // 缓冲流close之后, 会自动帮你关闭输入流 fis.close()
}
}
BufferedOutputStream
package Buffered;
import java.io.*;
/*
* 使用字节缓冲流写入
* BufferedOutputStream
* @time 2023年9月11日14:19:47
* @author _LJaXi
* @tip 想秀阿卡丽
* */
public class OutputStream {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("d:\\aaa.txt", true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
String data = "LOL";
bos.write(data.getBytes()); // 写入 8k 到缓冲区
fos.flush(); // 刷新到硬盘
/*---------------------------------------------------------------
* bos.flush()的作用是将缓冲区中的数据立即刷新(写入)到硬盘中
* 当使用BufferedOutputStream写入数据时,数据通常会先被存储在内部的缓冲区中,直到缓冲区达到一定的容量或者手动调用flush()方法
* ---------------------------------------------------------------
* flush()方法的使用是为了确保数据被及时写入硬盘,而不是一直停留在缓冲区
* 在调用flush()方法后,任何未写入的数据将被立即写入到硬盘中,这样可以避免数据丢失的风险
* ---------------------------------------------------------------
* 在流关闭之前或发生异常时,也会自动调用flush()方法,确保所有数据都被写入硬盘
* ---------------------------------------------------------------*/
bos.close(); // 内部也会调用 flush() 方法
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象流
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能 {
readObject()
从流中读取一个对象
writeObject(Object obj)
向流中写入一个对象}
使用流传输对象的过程称为序列化(写入)、反序列化(读取)
Student 类
package ObjectStream;
import java.io.Serializable;
// 要想序列化,类必须实现一个接口,为标记接口
public class Student implements Serializable {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// this is 重写 toString 方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
ObjectOutStream
package ObjectStream;
import java.io.*;
/*
* 序列化类必须要实现 Serializable 接口(标记接口)
* ObjectOutputStream
* @time 2023年9月14日13:49:52
* @author _LJaXi
* @tip 阿卡丽5连败
* */
public class OutStream {
public static void main(String[] args)throws IOException {
// 1. 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\aaa.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 2. 序列化(写入操作)
Student zs = new Student("张三", 20);
oos.writeObject(zs);
// 3. 关闭
oos.close();
System.out.println("序列化完毕");
}
}
ObjectInputSteam
package ObjectStream;
import java.io.*;
/*
* ObjectInputStream 反序列化(读取重构成对象)
* @time 2023年9月14日23:31:23
* @author _LJaXi
* @tip 阿卡丽排位3连胜
* */
public class InputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 1. 创建对象流
FileInputStream fis = new FileInputStream("d:\\aaa.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
// 2. 读取文件(反序列化)
Student s = (Student)ois.readObject();
// Student s2 = (Student)ois.readObject(); // 不能读取多次
// 3. 关闭
ois.close();
System.out.println("执行完毕");
System.out.println(s.toString());
}
}
序列化和反序列化注意点
序列化类必须实现 Serializable 接口
序列化类中对象属性要求实现 Serializable 接口
序列化类中对象属性要求实现 Serializable 接口意思为:
public class Student implements Serializable {
private String name;
private int age;
private Class class; // Class类要实现 Serializable 接口
// ... 其他内容
}
正在更新 ING…