I/O流
1 定义
数据在两个设备间的传输称为流,流是一组有顺序的,有起点和终点的字节集合;
I是input的缩写,表示输入流;
O是output的缩写,表示输出流;
java.io.* | ||||
父类 | 子类 | 子类 | ||
字节流 | 输入流 | InputStream | FileInputStream | DataInputStream |
输出流 | OutputStream | FileOutputStream | DataInputStream | |
字符流 | 输入流 | Reader | FileReader | |
BufferReader | ||||
输出流 | Writer | FileWriter | ||
BufferWriter |
2 分类
根据数据流向的不同分为:
输入流:数据由文件流向程序(读文件)
输出流:数据由程序流向文件(写文件)
根据数据类型的不同分为:
字节流:数据流中最小的数据单元是字节
字符流:数据流中最小的数据单元是字符,Java中的字符是Unicode编码,一个字符占用两个字节
3 字节流
//读文件的数据
public static void readData() throws IOException {
File file = new File("E://A1/User.txt");
//字节输入流
InputStream in = new FileInputStream(file);
//返回接下来从此输入流读取的字节数
int size = in.available();
for (int i = 0; i < size; i++) {
//读取文件数据,因为是字节流,返回的都是数字,所以需要转型成char字符
//read()方法,返回的是ascii码的十进制数,每个数字对应一个字符
char res = (char) in.read();
System.out.print(res);
}
}
//向文件写入数据
public static void writeData() throws IOException {
File file = new File("E://A1/User.txt");
//待写入的数据
String str = "中国";
//字节输出流
OutputStream out = new FileOutputStream(file);
//向文件写入数据
out.write(str.getBytes());
//关闭输出流
out.close();
}
4 字符流
//读文件
public static void readFile(String path) throws IOException {
File file = new File(path);
//创建字节输入流
InputStream in = new FileInputStream(file);
//字节输入流 转换 为字符输入流,并设置字符流编码为国际码UTF-8
InputStreamReader reader = new InputStreamReader(in, "UTF-8");
//字符流处理类
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();//读取一行数据,如果没有数据返回null
while (line != null) {
System.out.println(line);
line = br.readLine();
}
br.close();//关闭输入流
}
//写文件
public static void writeFile(String path) {
File file = new File(path);
OutputStream out = null;
OutputStreamWriter writer = null;
BufferedWriter bw = null;
try {
//创建字节输出流
out = new FileOutputStream(file);
//字节流转字符流
writer = new OutputStreamWriter(out);
//字符流处理类
bw = new BufferedWriter(writer);
bw.write("123");//向文件写入数据
bw.newLine();//换行
bw.write("abc");
bw.write("你好");
bw.flush();//刷新输出流,执行该方法后,数据才会被写入到文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭字符输出流
if (bw != null) bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5 File类常用方法
方法名 | 返回值类型 | 说明 | 示例 |
exists() | boolean | 判断文件或文件夹是否存在 | |
isFile() | boolean | 判断是否是文件 | |
isDirectory() | boolean | 判断是否是文件夹(目录) | |
list() | String[] | 获取当前目录下的所有文件名 | |
listFiles() | File[] | 获取当前目录下的所有文件对象 | |
delete() | void | 删除文件或文件夹 | |
deleteOnExit() | void | 当文件或文件夹存在,则执行删除 |
6 IO流复制大文件
public static void copyMediaFile() {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(new File("E://冒泡排序.mp4"));
out = new FileOutputStream(new File("E://冒泡排序_new.mp4"));
//创建一个字节数组,用于接收读取到的字节
byte[] buf = new byte[1024];
//将读取到的字节数据存放到字节数组中,每次只能存字节固定长度的数据
int len = in.read(buf);
while (len != -1) {
//向新文件写入字节中的数据
//write(字节数组,写入的开始位置,写入的数据长度)
out.write(buf, 0, len);
out.flush();
len = in.read(buf);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
7 序列化与反序列化
序列化:将对象转换成特定格式的字符串叫做序列化;
反序列化:将特定的字符串转换为对象叫做反序列化;
transient关键字:
//transient透明的,序列化的时候不予考虑
transient int no = 1;
实现接口 java.io.Serializable
/*
* 序列化
* 将对象转换为特定格式的字符串叫做序列化;
* 将特定的字符串转换为对象叫做反序列化;
*
* 对象的序列化主要有两种用途:
* 1)把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中;
* 2)在网络上传送对象的字节序列。
*
* 序列化id的作用:
* 序列化ID起着关键的作用,java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。
* 反序列化时,JVM会把传来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,
* 如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。
*/
public class User implements Serializable{
//序列化id
private static final long serialVersionUID = 202112301109476172L;
private String name;
public User() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//序列化
User user = new User();
user.setName("hudl");
//objectOutputStream 对象输出流
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream(
new File("d://User.txt")
));
//写入对象
out.writeObject(user);
System.out.println("对象序列化成功!!!");
out.close();
//反序列化
ObjectInputStream in = new ObjectInputStream(
new FileInputStream(
new File("d://User.txt")));
//将对象输入流转换为对象
User u2 = (User) in.readObject();
System.out.println("对象反序列化成功!");
System.out.println(u2.getName());
//生成序列化id
int rd = new Random().nextInt(99999);//随即范围[0.100000]
System.out.println(rd);
//时间戳
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String first = sf.format(new Date());
System.out.println(first);
}