08-java之io流基础
io流学习流程
说白了,本节的目的就是对 文件增删改查,先说一下学习顺序吧
- 定位文件
- File类可以定位文件:可以进行删除文件内容,读取文件本身信息等操作,但是不能读写文件内容
- 字符集
- 想要读取文件中的数据,就必须知道数据的底层形式(字节,字符)
- 读写文件内容
- IO流可以对硬盘中的文件进行读写
File类
File类学习流程
- 如何创建一个File类
- 使用File类,创建、删除、判断、获取
- 遍历文件夹
- 删除文件夹
File类概述和构造方法
-
File类介绍
- 它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
File类的构造方法
方法名 | 说明 |
---|---|
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 |
File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的 File实例 |
File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的 File实例 |
- 示例代码
public class FileDemo01 {public static void main(String[] args) {//File(String pathname): 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例File f1 = new File("E:\\\\iotest\\\\java.txt");System.out.println(f1);//File(String parent, String child): 从父路径名字符串和子路径名字符串创建新的 File实例File f2 = new File("E:\\\\iotest","java.txt");System.out.println(f2);//File(File parent, String child): 从父抽象路径名和子路径名字符串创建新的 File实例File f3 = new File("E:\\\\iotest");File f4 = new File(f3,"java.txt");System.out.println(f4);}
}
绝对路径和相对路径
- 绝对路径
是一个完整的路径,从盘符开始 - 相对路径
是一个简化的路径,相对当前项目下的路径 - 示例代码
public class FileDemo02 {public static void main(String[] args) {// 是一个完整的路径,从盘符开始File file1 = new File("D:\\\\iotest\\\\a.txt");// 是一个简化的路径,从当前项目根目录开始File file2 = new File("a.txt");File file3 = new File("模块名\\\\a.txt");}
}
File类创建功能-通过File创建文件
- 方法分类
方法名 | 说明 |
---|---|
public boolean createNewFile() | 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 |
public boolean mkdir() | 创建由此抽象路径名命名的目录 |
public boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 |
- 示例代码
import java.io.File;
import java.io.IOException;public class FileDemo02 {public static void main(String[] args) throws IOException {//需求1:我要在E:\\\\iotest目录下创建一个文件java.txtFile f1 = new File("E:\\\\iotest\\\\java.txt");File parentFile = f1.getParentFile(); // E:\\iotest 就是获取上一个文件夹/文件的内容System.out.println("创建文件夹,解决因为文件不存在发生的异常:" + parentFile.mkdirs());System.out.println("创建一个文件:" + f1.createNewFile()); // //注意点:文件所在的文件夹必须要存在.System.out.println("--------");//需求2:我要在E:\\\\iotest目录下创建一个目录JavaSE,不能创建多级File f2 = new File("E:\\\\iotest\\\\JavaSE");System.out.println(f2.mkdir());System.out.println("--------");//需求3:我要在E:\\\\iotest目录下创建一个多级目录JavaWEB\\\\HTMLFile f3 = new File("E:\\\\iotest\\\\JavaWEB\\\\HTML");System.out.println(f3.mkdirs());System.out.println("--------");// 获取当前模块路径String currentPath=System.getProperty("user.dir");//需求4:我要在当前模块目录下创建一个多级目录JavaWEB\\\\HTMLFile f4 = new File("iotest4\\\\java.txt");if( f4.getParentFile() != null && f4.getParentFile().mkdirs()){System.out.println("成功创建文件夹");}System.out.println("创建一个文件:" + f4.createNewFile());}
}
File类删除功能
Java中File.delete删除当前文件或者文件夹,java删除的文件,将会直接删除,不会进入回收站。
如果删除的是文件夹,则该文件必须为空,如果要删除一个非空的文件夹,则需要首先删除该文件夹下面每个文件和文件夹,才可以删除。
- 方法分类
方法名 | 说明 |
---|---|
public boolean delete() | delete方法只能删除文件和空文件夹 |
- 示例代码
public class FileDemo03 {public static void main(String[] args) throws IOException {// 获取当前模块路径String currentPath=System.getProperty("user.dir");// 删除文件File f1 = new File("iotest\\\\java.txt");f1.delete();// 删除目录File f2 = new File("iotest");f2.delete();}
}
File类判断和获取功能
- 判断功能
方法名 | 说明 |
---|---|
public boolean isDirectory() | 测试此抽象路径名表示的File是否为目录 |
public boolean isFile() | 测试此抽象路径名表示的File是否为文件 |
public boolean exists() | 测试此抽象路径名表示的File是否存在 |
- 获取功能
方法名 | 说明 |
---|---|
public String getAbsolutePath() | 返回此抽象路径名的绝对路径名字符串 |
public String getPath() | 将此抽象路径名转换为路径名字符串 |
public String getName() | 返回由此抽象路径名表示的文件或目录的名称 |
public File[] listFiles() | 返回此抽象路径名表示的目录中的文件和目录的File对象数组 |
- 示例代码
public class FileDemo04 {public static void main(String[] args) {//创建一个File对象File f = new File("myFile\\\\java.txt");// public boolean isDirectory():测试此抽象路径名表示的File是否为目录
// public boolean isFile():测试此抽象路径名表示的File是否为文件
// public boolean exists():测试此抽象路径名表示的File是否存在System.out.println(f.isDirectory());System.out.println(f.isFile());System.out.println(f.exists());// public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
// public String getPath():将此抽象路径名转换为路径名字符串
// public String getName():返回由此抽象路径名表示的文件或目录的名称System.out.println(f.getAbsolutePath());System.out.println(f.getPath());System.out.println(f.getName());System.out.println("--------");// public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的File对象数组File f2 = new File("E:\\\\iotest");File[] fileArray = f2.listFiles();for(File file : fileArray) {
// System.out.println(file);
// System.out.println(file.getName());if(file.isFile()) {System.out.println(file.getName());}}}
}
File类练习-遍历文件夹下所有文件-控制台以树形展示
- 案例需求
遍历文件夹下所有文件
打印格式如下:
filemodule
|_aaa
|__a.txt
|___111.txt 0MB
|__b.txt 0MB
- 代码实现
import java.io.File;class FileSystem {public static void main(String[] args) {File f = new File("filemodule");// 指定文件位置System.out.println(f.getName());// 打印在这个文件下地文件夹;tree(f, 1);// 方法!进入子文件夹中 并打印子文件名}private static void tree(File f, int level) {File[] childs = f.listFiles();// 返回一个抽象路径名数组,这些路径名表示此抽象路径名所表示目录中地文件for (int i = 0; i < childs.length; i++) {// 打印前缀for (int j = 0; j < level; j++) {if (j == 0) {System.out.print("|_");} else {System.out.print("_");}}if (childs[i].isDirectory()) { //System.out.println(childs[i].getName());// 打印子文件地名字tree(childs[i], level + 1);} else {System.out.println(childs[i].getName() + "\\t\\t\\t\\t\\t" + childs[i].length() / 1024 / 1024 + "MB");// 如果是文件把大小也打印出来}}}
}
File类练习-删除文件夹所有内容
- 案例需求
删除一个多级文件夹 - 实现步骤
-
- 定义一个方法,接收一个File对象
- 遍历这个File对象,获取它下边的每个文件和文件夹对象
- 判断当前遍历到的File对象是文件还是文件夹
- 如果是文件夹,递归调用自己,将当前遍历到的File对象当做参数传递
- 将得到的文件或者空目录删除
- 参数传递过来的文件夹File对象已经处理完成,最后直接删除这个空文件夹
- 代码实现
import java.io.File;public class Test2 {public static void main(String[] args) {/* delete方法只能删除文件和空文件夹* 如果现在要删除一个有内容的文件夹* 先删掉这个文件夹里面所有的内容* 最后再删除这个文件夹*/File src = new File("iotest2");remove(src);}/* 删除指定文件夹下的全部内容 @param file*/public static void remove(File file) {File[] files = file.listFiles();//将file子目录及子文件放进文件数组if (files != null) {//如果包含文件进行删除操作for (int i = 0; i < files.length; i++) {if (files[i].isDirectory()) {//通过递归方法删除子目录的文件remove(files[i]);}files[i].delete();//删除子目录/子文件}file.delete(); // 删除传过来的目录}}
}
字符集
字符集相关概念
我们是怎么把文字存储到计算机的
- 我们把文字转换成十进制的表现方式(比如“a”相当于97),然后转换成二进制,然后就可以存储到计算机。
什么是字符集?什么叫字符编码
字符集(Character set)是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等
- 字符集:规定了字符和字符码之间的对应关系。 可以将字符集理解成一个很大的表格,它列出了所有字符和二进制的对应关系,计算机显示文字或者存储文字,就是一个查表的过程。
- 字符编码:规定了一个字符码在计算机中如何存储。
常用字符集
-
ASCII字符集(American Standard Code for Information Interchange,美国信息交换标准代码)
- 是最早产生的编码规范,包括数字、英文、符号
- 一个字节存储一个字符,也就是8位,总共可以表示128个字符信息(2^8=256,不包括负数)
-
GBK(即“国标”“扩展”汉语拼音的第一个字母) 字符集:全称《汉字内码扩展规范》
- window系统默认的码表。兼容ASCII码表,包括中日韩
- 一个中文以两个字节存储,英文1个字节
- Unicode字符集(又叫万国码、统一码):是计算机科学领域里的一项业界字符编码规范
- Unicode包含了全世界所有的字符,兼容ASCII 。Unicode最多可以保存4个字节容量的字符。也就是说,要区分每个字符,每个字符的地址需要4个字节。这是十分浪费存储空间的,于是,程序员就设计了几种字符编码方式,比如:UTF-8,UTF-16,UTF-32。最广为程序员使用的就是UTF-8,UTF-8是一种变长字符编码,注意:UTF-8不是编码规范,而是编码方式。
- utf-8:一个中文以3个字节存储,英文1个字节
- Unicode包含了全世界所有的字符,兼容ASCII 。Unicode最多可以保存4个字节容量的字符。也就是说,要区分每个字符,每个字符的地址需要4个字节。这是十分浪费存储空间的,于是,程序员就设计了几种字符编码方式,比如:UTF-8,UTF-16,UTF-32。最广为程序员使用的就是UTF-8,UTF-8是一种变长字符编码,注意:UTF-8不是编码规范,而是编码方式。
小结
- 英文和数字在任何国家的字符集中都占一个字节(在任何国家的编码中都不会乱码)
- GBK中一个中文字符2个字节
- UTF-8中一个中文字符3个字节
- 编码前的字符集和编码后的字符集必须一致,否则乱码
- 中文的字节存储方式
- 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
- 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
字符集的编码、解码操作
代码如下:
class FileSystem {public static void main(String[] args) throws UnsupportedEncodingException {String str = "a1爱";byte[] gbks1 = str.getBytes();System.out.println(gbks1.length);System.out.println("以当前默认字符集编码:" + Arrays.toString(gbks1));System.out.println("以当前默认字符集解码:" + new String(gbks1));byte[] gbks2 = str.getBytes("GBK");System.out.println(gbks2.length);System.out.println("指定以GBK编码:" + Arrays.toString(gbks2));System.out.println("以当前默认字符集解码GBK编码的数据:" + new String(gbks2));System.out.println("指定以GBK解码:" + new String(gbks2,"GBK"));}
}
输出如下
5
以当前默认字符集编码:[97, 49, -25, -120, -79]
以当前默认字符集解码:a1爱
4
指定以GBK编码:[97, 49, -80, -82]
以当前默认字符集解码GBK编码的数据:a1��
指定以GBK解码:a1爱
汉字的存储和解析过程
IO流
IO流的使用流程
- 创建输入/输出流
- 读/写 操作
- 关闭输入/输出流
IO流的概念与作用
I/O是Input/Output的缩写, 用于处理设备之间的数据传输。如读/写文件,网络通讯等。
流是一种抽象概念,它代表了数据的无结构化传递。
Java程序中,对于数据的输入/输出操作以”流(stream)” 的方式进行,所以叫io流。java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。常见的应用: 文件复制; 文件上传; 文件下载
IO流的分类
按照数据的流向(方向)
- 输入流:读数据,是数据从硬盘文件读入到内存的过程 =》 硬盘->内容
- 输出流:写数据,是内存程序的数据从内存写出到硬盘文件的过程=》内存->硬盘
按照数据类型(单位)
- 字节流:以字节为单位,可以读写所有数据
- 字符流:以字符为单位
使用场景
如果操作的是纯文本,比如json文件,txt文件,优先使用字符流
- 怎么判断是纯文本呢? 能用记事本打开并且能看懂的就是纯文本
如果是图片、视频、音频等二进制文件,优先使用字节流
如果不确认文件类型,优先使用字节流,字节流是万能的流
IO流体系结构图
字节流(byte) | 字符流(char) | |||
---|---|---|---|---|
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
抽象基类 | InputStream | OutputStream | Reader | Writer |
操作文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
操作数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象操作流 | ObjectInputStream | ObjectOutputStream | ||
打印流 | PrintStream | PrintWriter |
其中,转换流都是字节流转字符流。
- OutputStreamWriter : 字节输出流 -> 字符输出流;
- InputStreamReader : 字节输入流 -> 字符输入流
对象操作流也叫序列化流
字节流/字符流基础操作
字节输入流InputStream主要方法:
-
read() :从此输入流中读取一个数据字节。
-
read(byte[] b) :从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
-
read(byte[] b, int off, int len) :从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
-
close():关闭此输入流并释放与该流关联的所有系统资源。
字节输出流OutputStream主要方法:
- write(byte[] b) :将 b.length 个字节从指定 byte 数组写入此文件输出流中。
- write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
- write(int b) :将指定字节写入此文件输出流。
- flush() :刷新流,之后还可以继续写数据
- close() :关闭此输入流并释放与该流关联的所有系统资源。
字符输入流Reader主要方法:
- read():读取单个字符。
- read(char[] cbuf) :将字符读入数组。
- read(char[] cbuf, int off, int len) : 将字符读入数组的某一部分。
- read(CharBuffer target) :试图将字符读入指定的字符缓冲区。
- close() :关闭此流,但要先刷新它。
字符输出流Writer主要方法:
-
write(char[] cbuf) :写入字符数组。
-
write(char[] cbuf, int off, int len) :写入字符数组的某一部分。
-
write(int c) :写入单个字符。
-
write(String str) :写入字符串。
-
write(String str, int off, int len) :写入字符串的某一部分。
-
flush() :刷新流,之后还可以继续写数据
-
close() :关闭此流,但再次之前刷新它。 一旦流已关闭,进一步的write()或flush()调用将导致抛出IOException。 关闭以前关闭的流无效。
另外,字符缓冲流还有两个独特的方法:
- BufferedWriter类newLine() :写入一个行分隔符。这个方法会自动适配所在系统的行分隔符。
- BufferedReader类readLine() :读取一个文本行。
注意:输出流必须刷新才能写入,当然也可以直接调用
close()
,他里面包含了flush
,但是使用close()
关闭流后就不能在使用了如上,常用方法
输入流都有read方法
输出流都有write,flush方法
字节输入流读文件
代码如下:
public class ByteInputStreamTest1 {public static void main(String[] args) throws IOException {/* 字节输入流的使用方式*/// 1、创建输入流 => InputStreamInputStream fileInputStream = new FileInputStream("aa.txt"); // abc123测试// 2、读文件// read() :从此输入流中读取一个数据字节。int read = fileInputStream.read();System.out.println(read); // 97System.out.println((char) read); // abyte[] buffered = new byte[3];// read(byte[] b) :从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。//int read1 = fileInputStream.read(buffered);//System.out.println(read1); // 读取的字符数量 => 3//System.out.println(Arrays.toString(buffered)); // [98, 99, 49]//System.out.println(new String(buffered)); // bc1// read(byte[] b, int off, int len) :从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。int read2 = fileInputStream.read(buffered, 0, 2);System.out.println(read2); // 2System.out.println(Arrays.toString(buffered)); // [98, 99, 0]System.out.println(new String(buffered)); // bc // 如果没有读取到呢吗返回-1// 3、关闭资源fileInputStream.close();}
}
字符输入流读文件
- 介绍
Reader: 用于读取字符流的抽象父类
FileReader: 用于读取字符流的常用子类 - 构造方法
方法名 | 说明 |
---|---|
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
- 成员方法
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
- 代码演示
import java.io.FileReader;
import java.io.IOException;public class InputStreamReaderDemo {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("myCharStream\\\\b.txt");//int read():一次读一个字符数据int ch;while ((ch = fr.read()) != -1) {System.out.print((char) ch);}// int read(char[] cbuf):一次读一个字符数组数据char[] chs = new char[1024];int len;while ((len = fr.read(chs)) != -1) {System.out.print(new String(chs, 0, len));}// 释放资源 fr.close(); }
}
字节输出流写数据
-
使用字节输出流写数据的步骤
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象的写数据方法
- 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
-
写数据的方法分类
方法名 | 说明 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) | 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) | 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
- 示例代码
package ioreview.bytestream;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo02 {public static void main(String[] args) throws IOException {// 1、创建输出流//FileOutputStream(String name):创建文件输出流以指定的名称写入文件//FileOutputStream fos = new FileOutputStream("fos.txt");// FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件FileOutputStream fos = new FileOutputStream(new File("fos.txt"));// 2、写入数据// void write(int b):将指定的字节写入此文件输出流fos.write(97);fos.write(98);fos.write(99);//void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流byte[] bys = {97, 98, 99};fos.write(bys);//byte[] getBytes():返回字符串对应的字节数组byte[] bys2 = "abc".getBytes();fos.write(bys2);// void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流fos.write(bys, 0, bys.length);fos.write(bys, 1, 1);// fos.flush(); // 刷新流,之后还可以继续写数据// 3、关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据fos.close();}
}
字符输出流写文件
- 介绍
Writer: 用于写入字符流的抽象父类
FileWriter: 用于写入字符流的常用子类 - 构造方法
方法名 | 说明 |
---|---|
FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(File file, boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
FileWriter(String fileName, boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象 |
- 成员方法
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str, int off, int len) | 写一个字符串的一部分 |
- 刷新和关闭的方法
方法名 | 说明 |
---|---|
flush() | 刷新流,之后还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
- 代码演示
import java.io.FileWriter;
import java.io.IOException;public class OutputStreamWriterDemo {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("myCharStream\\\\a.txt");//void write(int c):写一个字符fw.write(97);fw.write(98);fw.write(99);// void writ(char[] cbuf):写入一个字符数组 char[] chs = {'a', 'b', 'c', 'd', 'e'};fw.write(chs);// void write(char[] cbuf, int off, int len):写入字符数组的一部分fw.write(chs, 0, chs.length);fw.write(chs, 1, 3);// void write(String str):写一个字符串fw.write("abcde");// void write(String str, int off, int len):写一个字符串的一部分fw.write("abcde", 0, "abcde".length());fw.write("abcde", 1, 3);// 释放资源fw.close();}
}
异常处理-处理释放资源
try-catch-finally
- 异常处理格式
- try-catch-finally
try{ 可能出现异常的代码;}catch(异常类名 变量名){ 异常的处理代码;}finally{ 执行所有清除操作;}
- 示例代码
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo04 {public static void main(String[] args) {//加入finally来实现释放资源 FileOutputStream fos = null;try {fos = new FileOutputStream("myByteStream\\\\fos.txt");fos.write("hello".getBytes());} catch (IOException e) {e.printStackTrace();} finally {try {//最后先关闭输出,在关闭输入,防止空指针异常加入ifif (fos != null) fos.close();} catch (IOException e) {e.printStackTrace();}}}
}
try-catch-resource
jdk1.7后增加了try-with-resources,他是一个声明一个或多个资源的try语句,且()
中只能放置资源对象,否则报错。一个资源作为一个对象,必须在程序结束之后关闭。try-with-resources语句确保在语句的最后每个资源都被关闭,任何实现了java.lang.AutoCloseable和java.io.Closeable的对象都可以使用try-with-resource来实现异常处理和关闭资源。
- 异常处理格式
- try-catch-resource
try(定义流对象){}catch(){}
- 示例代码
public class Test9 {
//JDK7改进方案public static void main(String[] args) {try (//这里只能放置资源对象,用完会自动关闭,自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)InputStream io = new FileInputStream("src/aaa.txt");OutputStream ot = new FileOutputStream("D:/www.txt");//int a=1;//报错这里只能写资源) {byte[] arr = new byte[1024];int len;while ((len = io.read(arr)) != -1) {ot.write(arr, 0, len);}System.out.println("文件拷贝成功");} catch (IOException e) {e.printStackTrace();}}
}
输出流写数据-换行/追加数据
-
写数据如何实现换行
- windows:\\r\\n
- linux:\\n
- mac:\\r
-
写数据如何实现追加写入
- public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
-
示例代码
import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamDemo03 {public static void main(String[] args) throws IOException {//创建字节输出流对象// FileOutputStream fos = new FileOutputStream("fos.txt");FileOutputStream fos = new FileOutputStream("fos.txt", true);// 写数据for (int i = 0; i < 10; i++) {fos.write("hello".getBytes());fos.write("\\r\\n".getBytes());}// 释放资源fos.close();}
}
如何使用字节输入流读取中文内容输出不乱码?
- 定义一个与文件一样大的字节数组,一次性读取文件全部字节,但是如果文件过大,字节数据可能溢出
字节流复制练习
字节文件输入/输出流
代码
package ioreview.bytestream;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/* @author 韦存滨* @className Test1* @description 文件字节输入/输出流 完成文件复制* @date 2023年02月11日 23:17*/
public class Test1 {public static void main(String[] args) {// 复制 - 其实下载也相当于一个复制,从网下下载到本地// 1、创建输出流/输出流FileInputStream fileInputStream = null;FileOutputStream fileOutputStream = null;try {fileInputStream = new FileInputStream("aa.txt");fileOutputStream = new FileOutputStream("bb.txt");// 2、读/写数据String data = "";byte[] bytes = new byte[1024];int length;while ((length = fileInputStream.read(bytes)) != -1) {// 输出文件到fileOutputStream.write(bytes, 0, length);data += new String(bytes);}System.out.println("输出的文件内容为:" + data);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {// 3、关闭流try {if (fileInputStream != null) {fileInputStream.close();}if (fileOutputStream != null) {fileOutputStream.close();}} catch (Exception e) {}}}}
字节数组输入/输出流
代码
package ioreview.bytestream;import java.io.*;/* @author 韦存滨* @className Test1* @description 字节数组输入/输出流 完成文件复制* @date 2023年02月11日 23:17*/
public class Test2 {public static void main(String[] args) {// 1、创建输出流/输出流ByteArrayInputStream byteArrayInputStream = null;ByteArrayOutputStream byteArrayOutputStream = null;try {String data = "abc123测试";byte[] dataBytes = data.getBytes();byteArrayInputStream = new ByteArrayInputStream(dataBytes);byteArrayOutputStream = new ByteArrayOutputStream();// 2、读/写数据byte[] bytes = new byte[3];int length;while ((length = byteArrayInputStream.read(bytes)) != -1) {byteArrayOutputStream.write(bytes, 0, length);System.out.println(byteArrayOutputStream);}// 2.1、获取文件内容byte[] bytes1 = byteArrayOutputStream.toByteArray();String s = new String(bytes1);System.out.println("读取的内容是:" + s);// 或者直接输出System.out.println("读取的内容是:" + byteArrayInputStream.toString());int size = byteArrayOutputStream.size();// 将此 byte 数组输出流的// count 字段重置为零,从而丢弃输出流中目前已累积的所有输出。通过重新使用已分配的缓冲区空间,// 可以再次使用该输出流//byteArrayOutputStream.reset();// 2.2、将此数组输出流的全部内容写入到指定的输出流参数中FileOutputStream fileOutputStream = new FileOutputStream("cc88.txt");byteArrayOutputStream.writeTo(fileOutputStream);} catch (IOException e) {e.printStackTrace();} finally {try {if (byteArrayInputStream != null) {byteArrayInputStream.close();}if (byteArrayOutputStream != null) {byteArrayOutputStream.close();}} catch (Exception e) {}}}
}
字节缓冲输入/输出流
代码
package ioreview.bytestream;import java.io.*;/* @author 韦存滨* @className Test1* @description 字节缓冲输入/输出流 完成文件复制* @date 2023年02月11日 23:17*/
public class Test3 {public static void main(String[] args) {// 1、创建输出流/输出流BufferedInputStream bufferedInputStream = null;BufferedOutputStream bufferedOutputStream = null;try {bufferedInputStream = new BufferedInputStream(new FileInputStream("aa.txt"));bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("bb.txt"));String data = "";byte[] bytes = new byte[1024];int length;while ((length = bufferedInputStream.read(bytes)) != -1) {data += new String(bytes);bufferedOutputStream.write(bytes, 0, length);}System.out.println("读取的内容是:" + data);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {// 3、关闭流try {if (bufferedInputStream != null) {bufferedInputStream.close();}if (bufferedOutputStream != null) {bufferedOutputStream.close();}} catch (Exception e) {}}}
}
字节缓冲流——old
缓冲流的主要作用就是提高流的读取,写入效率。
- 操作方式:字节流字节操作文件,字节缓冲流先将数据添加到缓冲区,再将数据写入到文件中(或者读取文件);
- 效率:字节缓冲流的效率要高于字节流;(例子:把一堆砖头从A地搬往B地,一块一块的搬(字节流)的效率要远低于 先把砖头装进小推车再运往B地(缓冲流))
字节缓冲流构造方法
- 构造方法:
方法名 | 说明 |
---|---|
BufferedOutputStream(OutputStream out) | 该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用 |
BufferedInputStream(InputStream in) | 创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节 |
- 示例代码
public class CopyAviDemo {public static void main(String[] args) throws IOException {//复制视频
// method1();method2();}//字节缓冲流一次读写一个字节数组public static void method2() throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\\\iotest\\\\字节流复制图片.avi"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\\\字节流复制图片.avi"));byte[] bys = new byte[1024];int len;while ((len=bis.read(bys))!=-1) {bos.write(bys,0,len);}bos.close();bis.close();}//字节缓冲流一次读写一个字节public static void method1() throws IOException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\\\iotest\\\\字节流复制图片.avi"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\\\字节流复制图片.avi"));int by;while ((by=bis.read())!=-1) {bos.write(by);}bos.close();bis.close();}}
案例-字节缓冲流复制视频
-
案例需求
把“E:\\itcast\\字节流复制图片.avi”复制到模块目录下的“字节流复制图片.avi” -
实现步骤
-
- 根据数据源创建字节输入流对象
- 根据目的地创建字节输出流对象
- 读写数据,复制视频
- 释放资源
-
代码实现
import java.io.*;public class FileCopy {public static void main(String[] args) {/* 复制文件*/BufferedInputStream in = null;BufferedOutputStream out = null;try {//abc.txt ->内存in = new BufferedInputStream(new FileInputStream("aa.jpg"));//内存 ->xyz.txtout = new BufferedOutputStream(new FileOutputStream("cc.jpg"));//开辟缓冲区 数组 将文件内容在数组中读取byte[] buf = new byte[1024];int len;// int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。//在不等于-1 说明文件里还有字节 一直输入直到 返回值为-1while ((len = in.read(buf)) != -1) {// void write(byte[]b,int off,int len)将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据out.write(buf, 0, len);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {//最后先关闭输出,在关闭输入,防止空指针异常加入ifif (out != null) out.close();if (in != null) in.close();} catch (IOException e) {e.printStackTrace();}}}}
字符流
为什么会出现字符流
- 字符流的介绍
- 由于字节流操作中文不是特别的方便,所以Java就提供字符流
- 字符流 = 字节流 + 编码表
字符串中的编码解码问题
- 相关方法
方法名 | 说明 |
---|---|
byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节 |
byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节 |
String(byte[] bytes) | 使用平台的默认字符集解码指定的字节数组来创建字符串 |
String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来创建字符串 |
- 代码演示
import java.io.UnsupportedEncodingException;
import java.util.Arrays;public class StringDemo {public static void main(String[] args) throws UnsupportedEncodingException {//定义一个字符串String s = "123中";byte[] bys1 = s.getBytes(); // 当前默认编码方式byte[] bys2 = s.getBytes("UTF-8");byte[] bys3 = s.getBytes("GBK");System.out.println(Arrays.toString(bys1)); // [49, 50, 51, -28, -72, -83]System.out.println(Arrays.toString(bys2)); // [49, 50, 51, -28, -72, -83]System.out.println(Arrays.toString(bys3)); // [49, 50, 51, -42, -48]String ss1 = new String(bys1); // 123中String ss2 = new String(bys1, "UTF-8"); // 123中String ss3 = new String(bys1, "GBK"); // 123涓�System.out.println(ss1);System.out.println(ss2);System.out.println(ss3);}
}
字符缓冲流
-
字符缓冲流介绍
- BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
- BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
-
构造方法
方法名 | 说明 |
---|---|
BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
BufferedReader(Reader in) | 创建字符缓冲输入流对象 |
- 代码演示
import java.io.*;public class BufferedStreamDemo01 {public static void main(String[] args) throws IOException {//BufferedWriter(Writer out)BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\\\bw.txt"));bw.write("hello\\r\\n");bw.write("world\\r\\n");bw.close();// BufferedReader(Reader in)BufferedReader br = new BufferedReader(new FileReader("myCharStream\\\\bw.txt"));// 一次读取一个字符数据int ch;while ((ch = br.read()) != -1) {System.out.print((char) ch);}// 一次读取一个字符数组数据char[] chs = new char[1024];int len;while ((len = br.read(chs)) != -1) {System.out.print(new String(chs, 0, len));}br.close();}
}
字符缓冲流特有功能
- 方法介绍
BufferedWriter:
BufferedReader:
方法名 | 说明 |
---|---|
void newLine() | 写一行行分隔符,行分隔符字符串由系统属性定义 |
方法名 | 说明 |
---|---|
String readLine() | 读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null |
- 代码演示
import java.io.*;public class BufferedStreamDemo02 {public static void main(String[] args) throws IOException {//创建字符缓冲输出流BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\\\bw.txt"));// 写数据for (int i = 0; i < 10; i++) {bw.write("hello" + i);bw.write("\\r\\n");bw.newLine();bw.flush();}// 释放资源bw.close();// 创建字符缓冲输入流BufferedReader br = new BufferedReader(new FileReader("myCharStream\\\\bw.txt"));String line;while ((line = br.readLine()) != null) {System.out.println(line);}br.close();}
}
转换流
字符流中和编码解码问题相关的两个类
- InputStreamReader:是从字节流到字符流的桥梁,父类是Reader
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集 - OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
转换流读写数据
- 构造方法
方法名 | 说明 |
---|---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
- 代码演示
import java.io.*;public class ConversionStreamDemo {public static void main(String[] args) throws IOException {OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt"));//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt"), "GBK");osw.write("中国");osw.close();InputStreamReader isr = new InputStreamReader(new FileInputStream("fos.txt"));//InputStreamReader isr = new InputStreamReader(new FileInputStream("fos.txt"), "GBK");// 一次读取一个字符数据int ch;while ((ch = isr.read()) != -1) {System.out.print((char) ch);}isr.close();}
}
对象操作流
对象序列化流
序列化:将对象的状态信息转换为可以存储或传输的形式的过程。程序通过序列化把Java对象转换成二进制字节流,然后就可以把二进制字节流写入网络或磁盘。
反序列化:读取磁盘或网络中的二进制字节流数据,转化为Java对象
序列化流:ObjectOutputStream
反序列化流:ObjectInputStream
注意事项
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
-
对象序列化介绍
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
-
对象序列化流: ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
-
构造方法
方法名 | 说明 |
---|---|
ObjectOutputStream(OutputStream out) | 创建一个写入指定的OutputStream的ObjectOutputStream |
- 序列化对象的方法
方法名 | 说明 |
---|---|
void writeObject(Object obj) | 将指定的对象写入ObjectOutputStream |
- 示例代码
学生类
测试类
public class Student implements Serializable {private String name;private int age;public Student() {}public Student(String name, int age) {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;}@Overridepublic String toString() {return "Student{" + "name='" + name + '\\'' + ", age=" + age + '}';}
}public class ObjectOutputStreamDemo {public static void main(String[] args) throws IOException {//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStreamObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));// 创建对象Student s = new Student("佟丽娅", 30);// void writeObject(Object obj):将指定的对象写入ObjectOutputStreamoos.writeObject(s);// 释放资源oos.close();}
}
对象反序列化流
-
对象反序列化流: ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
-
构造方法
方法名 | 说明 |
---|---|
ObjectInputStream(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
- 反序列化对象的方法
方法名 | 说明 |
---|---|
Object readObject() | 从ObjectInputStream读取一个对象 |
- 示例代码
public class ObjectInputStreamDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStreamObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));//Object readObject():从ObjectInputStream读取一个对象Object obj = ois.readObject();Student s = (Student) obj;System.out.println(s.getName() + "," + s.getAge());ois.close();}
}
serialVersionUID&transient
-
serialVersionUID
-
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,会抛出InvalidClassException异常
-
如果出问题了,如何解决呢?
- 重新序列化
-
给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;
-
-
transient
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
-
示例代码
学生类
测试类
public class Student implements Serializable {//private static final long serialVersionUID = 42L;private String name;//private int age;private transient int age;public Student() {}public Student(String name, int age) {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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\\'' +", age=" + age +'}';}
}public class ObjectStreamDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {write();read();}//序列化private static void write() throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));Student s = new Student("佟丽娅", 20);oos.writeObject(s);oos.close();}//反序列化private static void read() throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));Object obj = ois.readObject();Student s = (Student) obj;System.out.println(s.getName() + "," + s.getAge());ois.close();}}
对象操作流练习
-
案例需求
创建多个学生类对象写到文件中,再次读取到内存中 -
实现步骤
-
- 创建序列化流对象
- 创建多个学生对象
- 将学生对象添加到集合中
- 将集合对象序列化到文件中
- 创建反序列化流对象
- 将文件中的对象数据,读取到内存中
-
代码实现
学生类
测试类
public class Student implements Serializable{private static final long serialVersionUID = 2L;private String name;private int age;public Student() {}public Student(String name, int age) {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;}
}
public class Demo03 {/* read():* 读取到文件末尾返回值是 -1* readLine():* 读取到文件的末尾返回值 null* readObject():* 读取到文件的末尾 直接抛出异常* 如果要序列化的对象有多个,不建议直接将多个对象序列化到文件中,因为反序列化时容易出异常* 建议: 将要序列化的多个对象存储到集合中,然后将集合序列化到文件中*/public static void main(String[] args) throws Exception {/*// 序列化//1.创建序列化流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myCode\\\\oos.txt"));ArrayList<Student> arrayList = new ArrayList<>();//2.创建多个学生对象Student s = new Student("佟丽娅",30);Student s01 = new Student("佟丽娅",30);//3.将学生对象添加到集合中arrayList.add(s);arrayList.add(s01);//4.将集合对象序列化到文件中oos.writeObject(arrayList);oos.close();*/// 反序列化//5.创建反序列化流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myCode\\\\oos.txt"));//6.将文件中的对象数据,读取到内存中Object obj = ois.readObject();ArrayList<Student> arrayList = (ArrayList<Student>)obj;ois.close();for (Student s : arrayList) {System.out.println(s.getName() + "," + s.getAge());}}
}
打印流
Properties集合
Properties作为Map集合的使用
-
Properties介绍
- 不属于io流体系,
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
-
Properties基本使用
package cc;import java.util.Properties;
import java.util.Set;public class PropertiesDemo01 {public static void main(String[] args) {//创建集合对象
// Properties<String,String> prop = new Properties<String,String>(); //错误Properties prop = new Properties();//存储元素prop.put("itheima001", "佟丽娅");prop.put("itheima002", "赵丽颖");prop.put("itheima003", "刘诗诗");//遍历集合Set<Object> keySet = prop.keySet();for (Object key : keySet) {Object value = prop.get(key);System.out.println(key + "," + value);}}
}
Properties作为Map集合的特有方法
- 特有方法
方法名 | 说明 |
---|---|
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
- 示例代码
package cc;import java.util.Properties;
import java.util.Set;public class PropertiesDemo02 {public static void main(String[] args) {//创建集合对象Properties prop = new Properties();//Object setProperty(String key, String value):设置集合的键和值,都是String类型prop.setProperty("itheima001", "佟丽娅");prop.setProperty("itheima002", "赵丽颖");prop.setProperty("itheima003", "刘诗诗");//String getProperty(String key):使用此属性列表中指定的键搜索属性
// System.out.println(prop.getProperty("itheima001"));
// System.out.println(prop.getProperty("itheima0011"));// System.out.println(prop);//Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串Set<String> names = prop.stringPropertyNames();for (String key : names) {
// System.out.println(key);String value = prop.getProperty(key);System.out.println(key + "," + value);}}
}
Properties和IO流相结合的方法
- 和IO流结合的方法
方法名 | 说明 |
---|---|
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
- 示例代码
package cc;import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;public class PropertiesDemo03 {public static void main(String[] args) throws IOException {//把集合中的数据保存到文件myStore();//把文件中的数据加载到集合myLoad();}private static void myLoad() throws IOException {Properties prop = new Properties();//void load(Reader reader):FileReader fr = new FileReader("fw.txt");prop.load(fr);fr.close();System.out.println(prop);}private static void myStore() throws IOException {Properties prop = new Properties();prop.setProperty("itheima001", "佟丽娅");prop.setProperty("itheima002", "赵丽颖");prop.setProperty("itheima003", "刘诗诗");//void store(Writer writer, String comments):FileWriter fw = new FileWriter("fw.txt");prop.store(fw, null);fw.close();}
}
Properties集合练习
-
案例需求
在Properties文件中手动写上姓名和年龄,读取到集合中,将该数据封装成学生对象,写到本地文件 -
实现步骤
-
- 创建Properties集合,将本地文件中的数据加载到集合中
- 获取集合中的键值对数据,封装到学生对象中
- 创建序列化流对象,将学生对象序列化到本地文件中
-
代码实现
学生类
测试类
public class Student implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;public Student() {}public Student(String name, int age) {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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\\'' +", age=" + age +'}';}
}
public class Test {public static void main(String[] args) throws IOException {//1.创建Properties集合,将本地文件中的数据加载到集合中Properties prop = new Properties();FileReader fr = new FileReader("prop.properties");prop.load(fr);fr.close();//2.获取集合中的键值对数据,封装到学生对象中String name = prop.getProperty("name");int age = Integer.parseInt(prop.getProperty("age"));Student s = new Student(name,age);//3.创建序列化流对象,将学生对象序列化到本地文件中ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));oos.writeObject(s);oos.close();}
}