IO流
io流框架
流的概念
- 流是内存与存储设备传输数据通道
- 水相当于数据,传输水管道相当于流
流的分类
- 按方向
- 输入流:从存储设备->内存
- 输出流:从内存->存储设备
- 按单位
- 字节流:以字节为单位,可以读写所有数据,所有数据都是字节B为单位
- 字符流:以字符为单位,只能读写文本数据,字符(1B,2B。。。都可能)
- 按功能
- 节点流:实现读写数据
- 过滤流:增强结点流
字节流
- 字节流父类
- InputStream:字节输入流,抽象
- OutputStream:字节输出流,抽象
FileInputStream类
- InputStream的实现类
- read(),每次读取一个字节,返回读取的ascii码
- read(bytes),读取多个,数量为数组bytes长度,返回读取的长度
- close关闭
package com.Io;
import java.io.FileInputStream;
import java.util.Arrays;
// FileInputStream
public class Demo01 {
public static void main(String[] args) throws Exception{
// 指定路径
FileInputStream fis = new FileInputStream("F:\\ava\\1.txt");
// 1返回字符对应ascii码
// int n = 0;
// while ((n=fis.read())!=-1){
// System.out.println((char) n);
// }
// 2返回此次读取长度
// byte[] bytes = new byte[3];
// int count1 = fis.read(bytes);
// System.out.println(count1);
// System.out.println(new String(bytes));
//
// int count2 = fis.read(bytes);
// System.out.println(count2);
// System.out.println(new String(bytes));
// 3循环多次读取
byte[] bytes = new byte[1024];
int count = 0;
while ((count=fis.read(bytes))!=-1){
System.out.println(count);
System.out.println(new String(bytes,0,count));
}
fis.close();
}
}
FileOutputStream类
- OutputStream的实现类
- write(x),将ascii码x对应的字符写入
- write(bytes),将字符数组bytes写入
- close(),关闭
package com.Io;
import java.io.FileOutputStream;
// FileOutputStream
public class Demo02 {
public static void main(String[] args) throws Exception{
// 方法无true,文件是先清空原来,再写,反之则继续写
FileOutputStream fos = new FileOutputStream("F:\\ava\\2.txt",true);
fos.write('a');
fos.write('b');
fos.write('c');
fos.write(97);
String s = "hello world";
fos.write(s.getBytes());
fos.close();
}
}
- 实现文件复制
- 通过输入流,将存储数据->内存,存于内存byte[]数组中
- 通过输出流,将内存数组->存储设备
package com.Io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Demo03 {
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("F:\\ava\\1.jpg");
FileOutputStream fos = new FileOutputStream("F:\\ava\\2.jpg",true);
int count = 0;
byte[] bytes = new byte[1024];
while ((count=fis.read(bytes))!=-1){
System.out.println(count);
fos.write(bytes,0,count);
}
fis.close();
fos.close();
}
}
字节缓冲流
- 设有缓冲区,提高io效率,减少访问磁盘次数
BufferedInputStream类
- 父类FilterInputStream,父父类InputStream
- FilterInputStream过滤流,加强型节点流,节点流FileInputStream,有基础的读写方法
- BufferInputStream,字节缓冲流,BufferInputStream设有缓冲区,提高io效率,减少访问磁盘次数
- 普通节点流需要多次读取,因为没有缓存区
package com.Io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
// BufferInputStream
public class Demo04 {
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("F:\\ava\\1.txt");
BufferedInputStream bis = new BufferedInputStream(fis);// 增强fis
// int data = 0;
// while ((data=bis.read())!=-1){
// System.out.println((char) data);
// }
int count = 0;
byte[] bytes = new byte[1024];
while ((count=bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,count));
}
bis.close();
}
}
BufferedOutputStream类
- 继承关系和上一样
- 将数据先写入缓存区,满了或者调用flush方法,再写入底层系统,不用一个一个写
- flush会刷新缓冲区,把缓冲区数据写入底层系统
package com.Io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
// BufferOutputStream
public class Demo05 {
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("F:\\ava\\buffer.txt");
BufferedOutputStream bis = new BufferedOutputStream(fos);
String s = "hello pixiv\n";
for (int i = 0; i < 10; i++) {
bis.write(s.getBytes());// 写入缓存区
bis.flush();// 刷新缓存区到存储文件
}
// 默认内调用flush
bis.close();
}
}
对象流
- ObjectOutputStream/ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能,可以操作对象
- 序列化:writeObject(Object obj),向流写入一个对象,内存->存储设备
- 反序列化:readObject(),从流读取一个对象,存储设备->内存
序列化/ObjectOutputStream类
-
ObjectOutputStream类
-
序列化,写入操作,写入对象到存储中
-
对应对象需要实现接口Serializable(可序列化的),只是一个标记,没重写的方法
public class Student implements Serializable
package com.Io;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class Demo06 {
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("F:\\ava\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student s1 = new Student("乐",10);
// 序列化(写入操作)
oos.writeObject(s1);
oos.close();
}
}
反序列化/ObjectInputStream类
- ObjectInputStream类
- 反序列化,读取操作,读取对象到内存
- 需要实现接口Serializable(可序列化的)
- 不能读取对象多次,会出现EOF异常,endoffile
package com.Io;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Demo07 {
public static void main(String[] args) throws Exception{
FileInputStream fio = new FileInputStream("F:\\ava\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fio);
// 反序列化,读取操作,不能读取多次
Student student = (Student)ois.readObject();
// Student student1 = (Student)ois.readObject();
ois.close();
System.out.println(student);
}
}
序列化注意事项
-
序列化类必须实现Serializable接口
-
类内的对象属性要求实现Serializable类,例如Student类内有一个Person对象,Person需要实现Serializable接口
-
序列化版本号ID,保证序列化类和反序列化类是同一个类
private static final long serialVersionUID = 100L; -
关键字,transient(瞬间的),不能序列化,显示默认值0或null
-
静态属性不能序列化,序列化是长保存
-
可以多次写入实现多次读取
-
通过集合实现多个对象的序列化和反序列化
Student s1 = new Student("乐",10);
Student s2 = new Student("孝",12);
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(s1);
arrayList.add(s2);
// 序列化(写入操作)
oos.writeObject(arrayList);
// 反序列化,读取操作,不能读取多次
ArrayList<Student> arrayList = (ArrayList<Student>) ois.readObject();
// Student student1 = (Student)ois.readObject();
ois.close();
System.out.println(arrayList);
字符流
字符编码
- UTF-8 针对Unicode码表的可变长度字符编码
- ISO-8856-1 asii码,西欧,希腊,泰语,阿拉伯,希伯来语对应文字符号
- GB2312 简中
- GBK 简中,简中
- BIG5 台湾,繁中
Reader和Writer
- 两抽象类Reader和Writer
- 子子类为FileReader和FileWriter
FileReader类
- 实现输入流,通过字符读取,每次字节数不一定
- FileInputStream,中文因为utf-8规定,一个汉字3个字节,普通字节流的单次读取为一次一个字节,会无法读取,不过数组读取也可以
package com.Io;
import java.io.FileReader;
public class Demo08 {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("F:\\ava\\3.txt");
// int data = 0;
// while ((data=fr.read())!=-1){// 一次一个字符char
// System.out.print((char) data);
// }
char[] chars = new char[1024];
int count = 0;
while ((count=fr.read(chars))!=-1){
System.out.println(new String(chars,0,count));
}
}
}
FileWriter类
- 实现输出流,通过字符输出
package com.Io;
import java.io.FileWriter;
public class Demo09 {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("F:\\ava\\3.txt");
String s = "java是世界最好语言";
// 写入
fw.write(s);// 可以直接写入字符和字符串,不用非要写入字节
// 刷新
fw.flush();
// 关闭
fw.close();
}
}
- 字符流复制文件
- 字符流不能复制图片,二进制文件,因为图片没有字符编码,read读取到内存变为乱码
package com.Io;
import java.io.FileReader;
import java.io.FileWriter;
// 字符流实现复制
// 字符流只能复制文本文件,不能复制二进制和图片
// 字节流都可以,因为所有文件都是字节组成
public class Demo10 {
public static void main(String[] args) throws Exception{
FileWriter fw = new FileWriter("F:\\ava\\n.txt");
FileReader fr = new FileReader("F:\\ava\\o.txt");
int count = 0;
char[] chars = new char[1024];
while ((count=fr.read(chars))!=-1){// 读取o到chars
System.out.println(new String(chars,0,count));
fw.write(chars,0,count);// chars写入n
fw.flush();
}
fw.close();
fr.close();
}
}
字符缓冲流
- 高效读写
- 支持输入换行符
- 可一次写一行,读一行
BufferedReader类
- 字符缓存输入流
- 可以自建缓冲区char[],也可以readline(),读一行
package com.Io;
import java.io.BufferedReader;
import java.io.FileReader;
public class Demo11 {
public static void main(String[] args) throws Exception{
FileReader fr = new FileReader("F:\\ava\\3.txt");
BufferedReader br = new BufferedReader(fr);
// // 自建缓存区读取
// int count = 0;
// char[] chars = new char[1024];
//
// while ((count= br.read(chars))!=-1){
// System.out.println(new String(chars,0,count));
// }
// 读一行,读到结束返回null
String s = null;
while ((s=br.readLine())!=null){
System.out.println(s);
}
}
}
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
@Autowired
protected SetmealDishService setmealDishService;
@Override
public void saveWithDish(SetmealDto setmealDto) {
this.save(setmealDto);
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().map((item) -> {
item.setSetmealId(setmealDto.getId());
return item;
}).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
}
浙公网安备 33010602011771号