IO流(二)
目录
- IO流 —— 字符流
- IO流 —— 缓冲流
- IO流 —— 转换流
- IO流 —— 打印流
- IO流 —— 数据流
- IO流 —— 序列化流
1.IO流 —— 字符流
- 文件字符输入流 —— 读字符数据进来
- 字节流:适合复制文件等,不适合读写文本文件
- 字符流:适合读写文本文件内容
FileReader(文件字符输入流)
- 作用:以内存为基准,可以把文件中的数据以字符的形式,读入到内存中去
构造器 | 说明 |
---|
Public FileReader(File file) | 创建字符输入流管道与源文件接通 |
Public FileReader(String Pathname) | 创建字符输入流管道与源文件路径接通 |
方法名称 | 说明 |
---|
Public int read() | 每次读取一个字符返回,如果发现没有数据可读会返回-1 |
Public int read(char[] buffer) | 每次用一个字符数组去读取数据,返回字符数组读取了多少个字符,如果发现没有数据可读会返回-1 |
掌握文件字符输入流每次读取一个字符
/**
* 目标:掌握文件字符输入流每次读取一个字符
*/
public class FileReaderTest1 {
public static void main(String[] args) {
try (
// 1、创建一个文件字符输入流管道与源文件接通
Reader fr = new FileReader("src/ab.txt")
) {
// 2、读取文本文件的内容
int c; // 记住每次读取的字符编号
while((c = fr.read()) != -1) {
System.out.print((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
掌握文件字符输入流每次读取多个字符
/**
* 目标:掌握文件字符输入流每次读取多个字符
*/
public class FileReaderTest2 {
public static void main(String[] args) {
try (
// 1、创建一个文件字符输入流管道与源文件接通
Reader fr = new FileReader("src/ab.txt")
) {
// 2、每次读取多个字符
char[] buffer = new char[3];
int len; // 记住每次读取了多少个字符
while((len = fr.read(buffer)) != -1) {
System.out.print(new String(buffer,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件字符输出流 (写字符数据出去)
作用:以内存为基准,把内存中的数据以字符的形式写出到文件中去
构造器 | 说明 |
---|
Public FileWriter(File file) | 创建字节输出流管道与源文件对象接通 |
Public FileWriter(String filePath) | 创建字节输出流管道与源文件路径接通 |
Public FileWriter(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
Public FileWriter(String filePath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
方法名称 | 说明 |
---|
void Writer(int c) | 写一个字符 |
void Writer(String str) | 写一个字符串 |
void Writer(String str,int off,int len) | 写一个字符串的一部分 |
void Writer(char[] cbuf) | 写一个字符数组 |
void Writer(char[] cbuf,int off,int len) | 写入字符数组的一部分 |
/**
* 目标:掌握文件字符输出流:写字符数据出去
*/
public class FileWriterTest2 {
public static void main(String[] args) {
try (
// 创建一个文件字符输出流管道与目标文件接通
// 覆盖管道
// Writer fw = new FileWriter("src/out02.txt");
// 追加数据的管道
Writer fw = new FileWriter("src/out02.txt",true)
) {
// 1、public void write(int c) : 写一个字符出去
fw.write('a');
fw.write(97);
fw.write('叶'); // 写一个字符出去
fw.write("\r\n");
// 2、public void write(String c) : 写一个字符串出去
fw.write("我爱你中国abc");
fw.write("\r\n");
// 3、public void writer(String c,int pos,int len) : 写字符串的一部分出去
fw.write("我爱你中国abc",0,5);
fw.write("\r\n");
// 4、public void write(char[] buffer) : 写一个字符数组出去
char[] buffer = {'张','三','z','h','a','n','g'};
fw.write(buffer);
fw.write("\r\n");
// 5、public void write(char[] buffer,int pos,int len) : 写字符数组的一部分出去
fw.write(buffer,0,2);
fw.write("\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符输出流使用时的注意事项
字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效
方法名称 | 说明 |
---|
Public void flush() throws IoException | 刷新流,就是将内存中缓存的数据立即写到文件中去生效 |
Public void close() throws IoException | 关闭流的操作,包含了刷新! |
/**
* 目标:搞清楚字符输出流使用时的注意事项
*/
public class FileWriterTest3 {
public static void main(String[] args) throws Exception {
// 字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效
Writer fw = new FileWriter("src/out03.txt");
// 写字符数据出去
fw.write('a');
fw.write('b');
fw.write('c');
fw.write('d');
fw.write("\r\n");
fw.write("我爱你中国abc");
fw.write("\r\n");
// fw.flush(); // 刷新流
// fw.write("张三"); // 刷新流后还可以往文件写数据
// fw.flush();
fw.close(); // 关闭流,关闭流里面包含刷新操作
}
}
字节流、字符流的使用场景小结
- 字节流适合做一切文件数据的拷贝(音视频,文本)
- 字节流不适合读取中文内容输出
- 字符流适合做文本文件的操作(读、写)
2.IO流——缓冲流
- 字节缓冲流
- 字符缓冲流
- 原始流、缓冲流的性能分析
![1](https://img-blog.csdnimg.cn/img_convert/e7d7d0cb973e3bff30875a36e7407094.png)
缓冲流的作用:对原始流进行包装,以提高原始流读写数据的性能
字节缓冲流的作用,提高字节流读写数据的性能
![2](https://img-blog.csdnimg.cn/img_convert/d67c2518c2040fb7a50988531f57bd0c.png)
- 原理:字节缓冲输入流自带8KB缓冲池,字节缓冲输出流也自带了8KB缓冲池
构造器 | 说明 |
---|
Public BufferedInputStream(InputStream is) | 把低级的字节输入流包装成一个高级的缓冲字节输入流,从而提高读取数据的性能 |
Public BufferedOutputStream(OutputStream os) | 把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
/**
* 目标:掌握字节缓冲流的作用
*/
public class BufferedInputStreamTest1 {
public static void main(String[] args){
try(
InputStream is = new FileInputStream("D:/reSource/logo.png");
// 1、定义一个字节缓冲输入流包装原始的字节输入流
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("C:/data/logo.png");
// 2、定义一个字节缓冲输出流包换原始的字节输出流
OutputStream bos = new BufferedOutputStream(os);
){
byte[] buffer = new byte[1024]; // 1KB
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
System.out.println("复制完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
BufferedReader(字符缓冲输入流)
- 作用:自带8KB(8192字节)的字符缓冲池,可以提高字符输入流读取数据的性能
构造器 | 说明 |
---|
Public BufferedReader(Reader r) | 把低级的字符输入流包装成字符缓冲输入流管道 |
方法 | 说明 |
---|
Public String readLine() | 读取一行数据返回,如果没有数据可读了,会返回null |
/**
* 目标:掌握字符缓冲输入流的用法
*/
public class BufferedReaderTest2 {
public static void main(String[] args) {
try (
Reader fr = new FileReader("src/ab.txt");
// 创建一个字符缓冲输入流包装原始的字符输入流
BufferedReader br = new BufferedReader(fr);
) {
// char[] buffer = new char[3];
// int len;
// while((len = fr.read(buffer)) != -1) {
// System.out.print(new String(buffer,0,len));
// }
String line; // 记住每次读取的一行数据
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedWriter(字符缓冲输出流)
- 作用:自带8KB(8192字节)的字符缓冲池,可以提高字符输出流写字符数据的性能
构造器 | 说明 |
---|
Public BufferedWriter(Writer r) | 把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能 |
方法 | 说明 |
---|
Public void newLine() | 换行 |
public class BufferedWriterTest3 {
public static void main(String[] args) {
try (
Writer fw = new FileWriter("src/out02.txt",true);
// 创建一个字符缓冲输出流管道包装原始的字符输出流
BufferedWriter bw = new BufferedWriter(fw);
) {
// 1、public void write(int c) : 写一个字符出去
bw.write('a');
bw.write(97);
bw.write('叶'); // 写一个字符出去
// fw.write("\r\n");
bw.newLine();
// 2、public void write(String c) : 写一个字符串出去
bw.write("我爱你中国abc");
// bw.write("\r\n");
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
案例:拷贝静夜思到另一个文件,恢复顺序
- 定义一个缓冲字符输入流管道与源文件接通
- 定义一个List集合存储读取的每行数据
- 定义一个循环按照行读取数据,存入到List集合中去
- 对List集合中的每行数据按照首字母编号升序排序
- 定义一个缓冲字符输出流管道与目标文件接通
- 遍历List集合中的每个元素,用缓冲字符输出管道写出来并换行
/**
* 案例:拷贝静夜思到另一个文件,恢复顺序
*/
public class Test4 {
public static void main(String[] args) {
try(
// 1、定义一个缓冲字符输入流管道与源文件接通
BufferedReader br = new BufferedReader(new FileReader("src/sort.txt"));
// 5、创建一个缓冲字符输出流管道与目标文件接通
BufferedWriter bw = new BufferedWriter(new FileWriter("src/Newsort.txt"));
) {
// 2、定义一个List集合存储读取的每一行
ArrayList<String> data = new ArrayList<String>();
// 3、按照行读取每段数据
String line; // 记录读取的当前行
while((line = br.readLine()) != null) {
data.add(line);
}
// 4、对ArrayList集合中的每段进行排序,默认按照每段首字母编号排序
Collections.sort(data);
// 6、遍历List集合的每段内容,依次写出到新文件中
for(String ln : data) {
bw.write(ln); // 输出遍历的当前段落
bw.newLine(); // 换行
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
原始流、缓冲流的性能分析
测试用例:
- 分别使用原始的字节流,以及字节缓冲流,赋值一个很大的视频文件
测试步骤:
- 使用低级的字节流按照一个一个字节的形式去复制文件
- 使用低级的字节流按照字节数组的形式复制文件
- 使用高级的缓冲字节流按照一个一个字节的形式复制文件
- 使用高级的缓冲字节流按照字节数组的形式复制文件
/**
* 目标:观察原始流和缓冲流的性能
*/
public class TimeTest4 {
// 复制视频的路径
private final static String SRC_FILE = "src/File1";
// 复制到哪个目的地
private final static String DEST_FILR = "D:\\";
public static void main(String[] args) {
// copy01(); // 低级字节流一个一个字节的形式复制,非常慢,直接淘汰
copy02(); // 低级字节流按照一个一个字节数组的形式复制,速度较慢
copy03(); // 缓冲流按照一个一个字节的形式的复制,速度较慢
copy04(); // 缓冲流按照一个一个字节数组的形式复制,速度极快,推荐使用!
}
private static void copy01() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
OutputStream os = new FileOutputStream(DEST_FILR + "1.avi");
) {
int b;
while((b = is.read()) != -1) {
os.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
private static void copy02() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
OutputStream os = new FileOutputStream(DEST_FILR + "2.avi");
) {
byte[] buffer = new byte[1024]; // 1KB
int len;
while((len = is.read(buffer)) != -1) {
os.write(buffer,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("低级字节流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
private static void copy03() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILR + "3.avi");
BufferedOutputStream bos = new BufferedOutputStream(os);
) {
int b;
while((b = bis.read()) != -1) {
bos.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("缓冲流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
private static void copy04() {
long startTime = System.currentTimeMillis();
try(
InputStream is = new FileInputStream(SRC_FILE);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(DEST_FILR + "4.avi");
BufferedOutputStream bos = new BufferedOutputStream(os);
) {
byte[] buffer = new byte[1024]; // 1KB
int len;
while((len = bis.read(buffer)) != -1) {
bos.write(buffer,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("缓冲流使用字节数组复制耗时:" + (endTime - startTime) / 1000.0 + "s");
}
}
3.IO——转换流
- 引出问题:不同编码读取时会乱码
- 字符输入转换流
- 字符输出抓换流
不同编码读取出现乱码的问题
- 如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码!
- 如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件时就会出现乱码!
/**
* 目标:掌握不同编码读取乱码的问题
*/
public class Test1 {
public static void main(String[] args) {
try(
// 1、创建一个文件字符输入流与源文件接通
// 代码编码:UTF-8 文件的编码:UTF-8
Reader fr = new FileReader("src/File1");
// // 代码编码:UTF-8 文件的编码:GBK
// Reader fr = new FileReader("src/File1"); // 乱码
// 2、把文件字符输入流包装成缓冲字符输入流
BufferedReader br = new BufferedReader(fr);
){
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
![3](https://img-blog.csdnimg.cn/img_convert/dcd553edc6f2555f2775e9c7fe8b216f.png)
InputStreamReader(字符输入转换流)
- 解决不同编码时,字符流读取文本内容乱码的问题
- 解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了
构造器 | 说明 |
---|
Public InputStreamReader(InputStream is) | 把原始的字节输入流,按照代码默认编码转成字符输入流(与直接使用FileReader的效果一样) |
Public InputStreamReader(InputStream is,String charset) | 把原始的字节输入流,按照指定字符集编码成字符输入流(重点) |
/**
* 目标:掌握字符输入转换流的作用
*/
public class InputStreamReaderTest2 {
public static void main(String[] args) {
try(
// 1、得到文件的原始字节流(GBK的字节流形式)
InputStream is = new FileInputStream("src/File2");
// 2、把原始的字节输入流按照指定的字符集编码转换成字符输入z转换流
Reader isr = new InputStreamReader(is, "GBK");
// 3、把字符输入流包装成缓冲字符输入流
BufferedReader br = new BufferedReader(isr);
) {
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
需要控制写出去的字符使用什么字符编码,该咋整?
- 调用String提供的getBytes方法解决、
- String data = “我爱你中国abc”;
- byte[] bytes = data.getBytes(“GBK”);
- OutputStreamWriter 字符输出转换流
- 作用:可以控制写出去的字符使用什么字符集编码
- 解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符编码了
构造器 | 说明 |
---|
Public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流,按照代码默认编码转换成字符输出流 |
Public OutputStreamWriter(OutputStream os,String charset) | 可以把原始的字节输出流,按照指定的编码转换成字符输出流(重点) |
/**
* 目标:掌握字符输出转换流的使用
*/
public class OutputStreamWriterTest3 {
public static void main(String[] args) {
try(
// 1、创建一个文件字节输出流
OutputStream os = new FileOutputStream("src/File3.txt");
// 2、把原始的字节输出流按照指定的字符集编码转换成字符输出流
Writer osw = new OutputStreamWriter(os,"GBK");
// 3、把字符输出流包装成缓冲字符输出流
BufferedWriter bw = new BufferedWriter(osw);
) {
bw.write("我爱你中国ABC");
bw.write("我是中国人abc");
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.IO——打印流
![4](https://img-blog.csdnimg.cn/img_convert/27f513d29c7bbf9b5e9c83aa854d8f82.png)
PrintStream / PrintWriter(打印流)
- 作用:打印流可以实现更方便,更高效的打印数据出去,能实现打印啥出去就是啥出去
PrintStream提供的打印数据的方案
构造器 | 说明 |
---|
Public PrintStream(OutputStream out / File / String) | 打印流直接通向字节输出流对象 / 文件 / 文件路径 |
Public PrintStream(String fileName,Charset charset) | 可以指定写出去的字符编码 |
Public printStream(OutputStream out,boolean autoFlush) | 可以指定实现自动刷新 |
Public printStream(OutputStream out,boolean autoFlush,String encoding) | 可以指定实现自动刷新,并可指定字符的编码 |
方法 | 说明 |
---|
Public void print(Xxx xxx) | 打印任意类型的数据出去 |
Public void Writer(int / byte[] / byte[] 一部分) | 可以支持写一个字节 / 一个字节数组 / 一个字节数组的一部分 出去 |
/**
* 目标:掌握打印流:PrintStream / PrintWriter的用法
*/
import java.io.PrintStream;
import java.nio.charset.Charset;
public class PrintTest1 {
public static void main(String[] args) {
try(
// 创建一个打印流管道
// PrintStream ps =
// new PrintStream("src/File3.txt",Charset.forName("GBK")); // 指定写出去的数据是"GBK"编码
PrintStream ps =
new PrintStream("src/File3.txt");
) {
ps.println(97); // 97
ps.println('a'); // 'a'
ps.println("张三"); // "张三"
ps.println(true); // true
ps.println(99.9); // 99.9
ps.write(97); // 'a'
} catch (Exception e) {
e.printStackTrace();
}
}
}
PrintWriter提供的打印数据的方案
构造器 | 说明 |
---|
Public printWriter(OutputStream out / Writer / File / String) | 打印流直接通向 字节输出流 / 字符输出流 / 文件 / 文件路径 |
Public printWriter(String filename,Charset charset) | 可以指定写出去的字符编码 |
Public printWriter(OutputStream out,boolean autoFlush,String encoding) | 可以指定实现自动刷新,并可指定字符的编码 |
public class PrintWriterTest2 {
public static void main(String[] args) {
try(
// 创建一个打印流管道
// PrintWriter ps =
// new PrintWriter("src/File4.txt");
// 创建一个打印流的追加管道
PrintWriter ps =
new PrintWriter(new FileOutputStream("src/File4.txt",true));
) {
ps.println(97);
ps.println('a');
ps.println("张三");
ps.println(true);
ps.println(99.9);
// ps.write(97); // 'a'
} catch (Exception e) {
e.printStackTrace();
}
}
}
PrintStream 和 PrintWriter 的区别
- 打印数据的功能是一模一样的,都是使用方便,性能高效
- PrintStream继承字节输出流OutputStream,因此支持写字节数据的方法
- PrintWriter继承自字符输出流Writer,因此支持写字符数据的方法
打印流的一种应用:输出语句的重定向
- 可以把输出语句的打印位置改到某个文件中去
- PrintStream ps = new PrintStream(“文件地址”); Sysout.setout(ps);
/**
* 目标:了解输出语句的重定向
*/
public class Test3 {
public static void main(String[] args) {
System.out.println("床前明月光"); // 输出到控制台
System.out.println("疑是地上霜"); // 输出到控制台
try(
PrintStream ps = new PrintStream("src/File5.txt");
){
// 把系统默认的打印流对象改成自己设置的打印流
System.setOut(ps);
System.out.println("举头望明月"); // 输出到指定的文件
System.out.println("低头思故乡"); // 输出到指定的文件
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.IO流——数据流
![6](https://img-blog.csdnimg.cn/img_convert/5ed86eecf04b31754ea1df1563838a4e.png)
DataOutputStream(数据输出流)
构造器 | 说明 |
---|
Public DataOutputStream(OutputStream out) | 创建新数据输出流包装基础的字节输出流 |
方法 | 说明 |
---|
Public final void writeByte(int V) throws IoException | 将byte类型的数据写入基础的字节输出流 |
Public final void writeInt(int V) throws IoException | 将int类型的数据写入基础的字节输出流 |
Public final void writeDouble(double V) throws IoException | 将double类型的数据写入基础的字节输出流 |
Public final void writeUTF(String str) throws IoException | 将字符串数据以 UTF-8 编码成字节写入基础的字节输出流 |
Public final void write(int / byte[] / byte[] 一部分) | 支持写一个字节 / 一个字节数组 / 一个字节数组的一部分出去 |
/**
* 目标:数据输出流
*/
public class DataOutputStreamTest1 {
public static void main(String[] args) {
try(
// 1、创建一个数据输出流包装低级的字节输出流
DataOutputStream dos =
new DataOutputStream(new FileOutputStream("src/File6out.txt"));
) {
dos.writeInt(97);
dos.writeDouble(99.9);
dos.writeBoolean(true);
dos.writeUTF("张三666");
} catch (Exception e) {
e.printStackTrace();
}
}
}
DataInputStream(数据输入流)
构造器 | 说明 |
---|
Public DataInputStream(InputStream is) | 创建新数据输入流包装基础的字节输入流 |
方法 | 说明 |
---|
Public final byte readByte() throws IoException | 读取字节数据返回 |
Public final int readInt() throws IoException | 读取int类型的数据返回 |
Public final double readDouble() throws IoException | 读取double类型的数据返回 |
Public final String readUTF() throws IoException | 读取字符串数据(UTF-8)返回 |
Public int readInt() / read(byte[]) | 支持读取字节数据进来 |
/**
* 目标:使用数据输入流读取特定类型的数据
*/
public class DataInputStreamTest2 {
public static void main(String[] args) {
try(
// 1、创建一个数据输入流包装一个低级字节输入流
DataInputStream dis =
new DataInputStream(new FileInputStream("src/File6out.txt"));
) {
int i = dis.readInt();
System.out.println(i);
double d = dis.readDouble();
System.out.println(d);
boolean b = dis.readBoolean();
System.out.println(b);
String rs = dis.readUTF();
System.out.println(rs);
} catch (Exception e) {
}
}
}
6.IO流——序列化流
- 对象序列化:把java对象写入到文件中去
- 对象反序列化:把文件里的java对象读出来
![6](https://img-blog.csdnimg.cn/img_convert/a5ee10147f5de580a17de9d81cd6696d.png)
ObjectOutputsream(对象字节输出流)
- 可以把java对象进行序列化:把java对象存入到文件中去
构造器 | 说明 |
---|
Public ObjectOutputStream(OutputStream out) | 创建对象字节输出流,包装基础的字节输出流 |
方法 | 说明 |
---|
Public final void writeObject(object o) throws IoException | 把对象写出去 |
/**
* 目标:掌握对象字节输出流的使用:序列化对象
*/
public class ObjectOutputStreamTest1 {
public static void main(String[] args) {
try(
// 2、创建一个对象字节输出流 包装原始的字节输出流
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("src/File7out.txt"));
) {
// 1、创建一个java对象
User u =new User("admin","张三",19,"123456");
// 3、序列化对象到文件中去
oos.writeObject(u);
System.out.println("序列化对象成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:对象如果要参与序列化,必须要实现序列化接口 (java.io.serializable)
ObjectInputStream(对象字节输入流)
- 可以把java对象进行反序列化,把存储在文件中的java对象读入到内存中来
构造器 | 说明 |
---|
Public object InputStream(InputStream is) | 创建对象字节输入流,包装基础的字节输入流 |
方法 | 说明 |
---|
Public final object readObject() | 把存储在文件中的java对象读出来 |
/**
* 目标:掌握对象字节输入流的使用:反序列化对象
*/
public class objectInputStreamTest2 {
public static void main(String[] args) {
try(
// 1、创建一个对象字节的输入流管道,包装低级的字节输入流与源文件接通
ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("src/File7out.txt"));
){
User u = (User)ois.readObject();
System.out.println(u);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果一次序列化多个对象,怎么弄?
- 用一个ArrayList集合存储多个对象,然后直接对集合进行序列化
- 注意:ArrayList集合已经实现了序列化接口(Serializable)
/**
* 目标:掌握对象字节输出流的使用:序列化多个对象
*/
public class ObjectOutputStreamTest2 {
public static void main(String[] args) {
try(
// 2、创建一个对象字节输出流 包装原始的字节输出流
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("src/File8out.txt"));
) {
// 1、创建多个java对象
User u1 =new User("zhangsan","张三",19,"123456");
User u2 =new User("lisi","李四",22,"123888");
User u3 =new User("wangwu","王五",19,"123666");
// 3、创建一个ArrayList集合存储多个对象 (ArrayList集合内部已经实现了序列化接口)
ArrayList<User> data = new ArrayList<User>();
data.add(u1);
data.add(u2);
data.add(u3);
// 4、序列化对象到文件中去
oos.writeObject(data);
System.out.println("序列化对象成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}