1.IO概述
1.1 什么是IO
我们把数据的传输看作是数据的流动,就像水流一样
I : Input,输入,即流向内存
O: Output, 输出,即流出内存
1.2 IO的分类
根据数据的流向分为输入流和输出流
- 输入流 : 把数据从其他设备读取到内存中的流
- 输出流: 把数据从内存中写到其他设备中的流
根据数据类型可分为字符流和字节流
2.字节流
一切均为字节
一切文件数据在存储时,都是以二进制数字的形式保存,都是一个个的字节,在传输时一样如此。所以,字节流可以传输任意文件数据。
字节输出流OutputStream
java.io.OutputStream
抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地,它定义了字节输出流的基本共性功能方法
void close()
: 关闭此输出流并释放与此流相关的任何系统资源void flush()
: 刷新此输出流并强制任何缓冲色输出字节被写出void write(byte[] b)
: 将从指定字节数组写入输出流void write(byte[] b, int off, int len)
: 从指定的字节数组写入len字节,从偏移off开始输出到此输出流。abstract void write(int b)
:将指定的字节写入此输出流
写入数据的原理:
java程序 --> JVM(java虚拟机) --> OS(操作系统)--> OS调用写数据的方法 --> 数据写入到文件
使用步骤:
1.创建FileOutputStream对象
2.调用对象的write()方法,将数据写入文件
3.释放资源
示例: 写入一个字节
import java.io.FileOutputStream;
public class demo01OutputStream {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(100); //如果是0--127的值会被编码成ASCII码,所以此处文件写入小写字母d
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
示例:一次写入多个字节
import java.io.FileOutputStream;
/*
如果想一次写多个字节,我们可以用字节数组作为参数传入write()方法
注意:
在字节数组中:
如果第一个字节是正数(0 -- 127),那么显示的时候会查询ASCII码表
如果死一个字节是负数,那么第一个数会和第二个数组合在一起形成一个中文显示,查询的是系统默认码表
*/
public class demo02OutputStream2 {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("src\\IO\\b.txt");
//要想写入100,需要3个字节
byte[] b = {49, 48, 48};
fos.write(b);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
示例: 写入字符
import java.io.FileOutputStream;
public class demo03OutputStream3 {
public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("src\\IO\\b.txt");
//String类中的getBytes()方法将字符串转化为字节数组
byte[] b = "你好世界".getBytes();
fos.write(b);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
字节输入流InputStream
这个抽象类是表示输入字节流的所有类的超类。 它定义了字节输入流的基本共性功能方法:
void close()
关闭此输入流并释放与流相关联的任何系统资源。
abstract int read()
从输入流读取数据的下一个字节。
int read(byte[] b)
从输入流读取一些字节数,并将它们存储到缓冲区 b 。
int read(byte[] b, int off, int len)
从输入流读取最多 len字节的数据到一个字节数组。
FileInputStream类
继承自InputStream类,将硬盘中的数据读取到内存中
构造方法
FileInputStream(File file)
通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(FileDescriptor fdObj)
创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
FileInputStream(String name)
通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
示例:一次读取一个字节
import java.io.FileInputStream;
import java.io.IOException;
public class demo04InputStream {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象
FileInputStream fis = new FileInputStream("src\\IO\\b.txt");
//2.使用对象的read()方法读取文件(读到文件的末尾会返回-1)
System.out.println(fis.read());
//3.释放资源
fis.close();
}
}
示例:一次读取多个字节
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
/*
一次读取多个字节
int read(byte[] bytes)
每次可读取的最大字节数即为传入的字节数组的长度
数组的长度一般定义为1024或1024的整数倍
数组起到缓冲作用,存储读取到的多个字节
返回值是本次读取的有效字节个数
没有读到数据返回-1
*/
public class demo05InputStream2 {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象
FileInputStream fis = new FileInputStream("src\\IO\\b.txt");
//2.使用对象的read()方法读取文件(读到文件的末尾会返回-1)
byte[] bytes = new byte[1024];
int len = 0;
while(len != -1){
// System.out.println(Arrays.toString(bytes));
System.out.println(new String(bytes,0, len));
len = fis.read(bytes);
}
//3.释放资源
fis.close();
}
}
示例:复制文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
复制文件:
1.读取文件
2.写入文件
*/
public class demoo6文件复制 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\exp1.jpg");
FileOutputStream fos = new FileOutputStream("src\\IO\\1.jpg");
int len = 0;
while((len = fis.read()) != -1){
fos.write(len);
}
//关闭资源(先关闭输出流,再关闭输入流)
fos.close();
fis.close();
}
//一次读多个字节
public static void copy() throws IOException {
FileInputStream fis = new FileInputStream("D:\\exp1.jpg");
FileOutputStream fos = new FileOutputStream("src\\IO\\1.jpg");
byte[] bytes = new byte[1024];
int len = 0;
while((len = fis.read()) != -1){
fos.write(bytes,0, len);
}
//关闭资源(先关闭输出流,再关闭输入流)
fos.close();
fis.close();
}
}
3.字符流
当使用字节流读取文件时,可能会遇到一些小问题,就是文件中有中文时,,可能不会显示完整的字符,因为一个中文字符占用多个字节。所以Java提供了字符流,以字符为单位读写数据,专门用于处理文本文件。
字符输入流Reader
java.io.Reader
抽象类是表示用于读取字符流的所有类的超类。定义了字符输入流的基本共性方法
abstract void close()
关闭流并释放与之相关联的任何系统资源。
int read()
读一个字符
int read(char[] cbuf)
将字符读入数组。
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的一部分。
FileReader类
使用方法和字节流类似
字符输出流Writer
java.io.Writer
抽象类是表示用于写入字符流的所有类的超类。定义了字符输出流的基本共性方法
abstract void close()
关闭流,先刷新。
abstract void flush()
刷新流。
void write(char[] cbuf)
写入一个字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(int c)
写一个字符
void write(String str)
写一个字符串
void write(String str, int off, int len)
写一个字符串的一部分。
FileWriter类
FileWriter类继承自OutputStreamWriter类
OutputStreamWriter类继承自Writer类
import java.io.FileWriter;
import java.io.IOException;
public class demo09FileWriter {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象
FileWriter fw = new FileWriter("src\\IO\\b.txt");
//2.使用write()方法,把数据写入到内存缓冲区
fw.write("我爱学习,学习使我快乐!");
//3.注意:数据并没有直接写入文件,需要调用flush()方法将数据刷新到文件中
fw.flush();
//4.释放资源(关闭之前会自动刷新)
fw.close();
}
}
续写和换行
FileWriter类的这两个构造方法可以传递一个布尔值表示是否续写:
FileWriter(File file, boolean append)
给一个File对象构造一个FileWriter对象。
FileWriter(String fileName, boolean append)
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
换行:
Windows: \r\n
Linux: /n
Mac: /r
4.Properties类
java.util.Properties
,继承自Hashtable,来表示一个持久的属性集。它使用键值对存储数据。每个键和值默认都是字符串。该类也被许多Java类使用,如获取系统属性时,System.getProperties
方法返回值就是一个Properties对象。
基本的存储方法
w
Object setProperty(String key, String value)
保存一对属性
String getProperty(String key)
使用此属性列表中指定的键搜索属性。(类似于Map中的get(key)方法)
Set<String> stringPropertyNames()
类似于Map中的put()方法
返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,w如果尚未从主属性列表中找到相同名称的键。
import java.util.Properties;
public class demo10Properties {
public static void main(String[] args) {
Properties p = new Properties();
//往集合中添加数据
p.setProperty("猪猪侠", "pig");
p.setProperty("喜羊羊","sheep");
p.setProperty("小熊熊","bear");
//遍历
for (String key : p.stringPropertyNames()) {
System.out.println(p.getProperty(key));
}
}
}
stroe方法
void store(OutputStream out, String comments)
将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法加载到 Properties表中的格式输出流。
void store(Writer writer, String comments)
将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式输出到输出字符流。
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class demo11Properties_store {
public static void main(String[] args) throws IOException {
Properties p = new Properties();
//往集合中添加数据
p.setProperty("猪猪侠", "pig");
p.setProperty("喜羊羊","sheep");
p.setProperty("小熊熊","bear");
//创建字节流
FileOutputStream fis = new FileOutputStream("src\\IO\\b.txt");
//写数据
p.store(fis, "");
//关闭资源
fis.close();
}
}
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class demo12Properties_store2 {
public static void main(String[] args) throws IOException {
Properties p = new Properties();
//往集合中添加数据
p.setProperty("猪猪侠", "pig");
p.setProperty("喜羊羊","sheep");
p.setProperty("小熊熊","bear");
//创建字符流
FileWriter fw = new FileWriter("src\\IO\\b.txt");
//写数据
p.store(fw, "");
//关闭资源
fw.close();
}
}
load方法
把硬盘中保存的文件(键值对)读取到集合中使用
void load(InputStream inStream)
从输入字节流读取属性列表(键和元素对)。
void load(Reader reader)
以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class demo13Properties_load {
public static void main(String[] args) throws IOException {
Properties p = new Properties();
/*
读取文件
注意:
1.存储键值对的文件中,键与值得连接符号可以用=,空格等
2.存储键值对得文件中,可以使用#进行注释,被注释的内容不会被读取到
3.存储键值对的文件中 ,键和值默认都字符串
*/
p.load(new FileReader("src\\IO\\b.txt")); //这里用字符流,因为字节流不能读取中文
//遍历
for (String spn : p.stringPropertyNames()) {
System.out.println(spn + " " + p.getProperty(spn));
}
}
}
5. 缓冲流
缓冲流,也叫做高效流,是对上面的IO流的增强
按数据类型分类:
- 字节缓冲流 :
BufferedInputStream
,BufferedOutputStream
- 字符缓冲流:
BufferedReader
,BufferedWriter
缓冲区的基本原理,是在创建流对象时,创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
字节缓冲输出流
构造方法
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class demo14BufferedOutputStream {
public static void main(String[] args) throws IOException {
//1.创建FileOutputStream对象
FileOutputStream fos = new FileOutputStream("src\\IO\\c.txt");
//2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象的效率
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.调用BufferedOutputStream对象的write()方法将数据写入缓冲区
bos.write("我爱学习,学习使我快乐!".getBytes());
//4.调用BufferedOutputStream对象的flush()方法将写的数据刷新到文件中(此步可选,关闭资源时会自动刷新)
bos.flush();
//5.关闭资源
bos.close();
}
}
字节缓冲输入流
构造方法
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。
BufferedInputStream(InputStream in, int size)
创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class demo15BufferedInputStream {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象
FileInputStream fis = new FileInputStream("src\\IO\\b.txt");
//2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的效率
BufferedInputStream bis = new BufferedInputStream(fis);
//3.调用BufferedInputStream对象的read()方法读取数据(读取方法同上文,可一次读一个字节,也可一次读多个字节)
int len = 0;
while((len = bis.read()) != -1)
System.out.println(len);
//5.关闭资源
bis.close();
}
}
字符缓冲输出流
构造方法
BufferedWriter(Writer out)
创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz)
创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class demo15BufferedWriter {
public static void main(String[] args) throws IOException {
//1.创建BufferedWriter对象,构造方法中传入FileWriter对象
BufferedWriter bw = new BufferedWriter(new FileWriter("src\\IO\\b.txt"));
//2.write()方法写数据
for (int i = 0; i < 10; i++) {
bw.write("我是一个粉刷匠");
bw.newLine(); //换行(用系统默认的换行符)
}
//3.关闭资源
bw.close();
}
}
字符缓冲输入流
构造方法
BufferedReader(Reader in)
创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)
创建使用指定大小的输入缓冲区的缓冲字符输入流。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class demo16BufferedReader {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("src\\IO\\b.txt"));
String line;
while((line = br.readLine())!= null){
System.out.println(line);
}
}
}
示例: 简单的文本排序
将以下文本排序
03.忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,渔人甚异之,复前行,欲穷其林。
13.余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”
15.南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终,后遂无问津者。
01.晋太元中,武陵人捕鱼为业。
07.复行数十步,豁然开朗。
08.土地平旷,屋舍俨然,有良田美池桑竹之属。
10.见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。
11.村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。
05.便舍船,从口入。
12.问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。
09.阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。
02.缘溪行,忘路之远近。
04.林尽水源,便得一山,山有小口,仿佛若有光。
06.初极狭,才通人。
14.既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。
import java.io.*;
import java.util.Map;
import java.util.TreeMap;
public class demo17文本排序 {
public static void main(String[] args) throws IOException {
Map<String, String> map = new TreeMap<>();
BufferedReader br = new BufferedReader(new FileReader("src\\IO\\b.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("src\\IO\\c.txt"));
//读数据并存入TreeMap(每一行文字的序号当作key,内容当作value,TreeMap会自动根据key排序)
String line;
while ((line = br.readLine()) != null) {
map.put(line.substring(0, 2), line.substring(2, line.length()));
}
//写数据
for (String s : map.keySet()) {
bw.write(s + map.get(s));
bw.newLine();//读取的内容不包含换行符,所以要自己换行
}
//关闭资源
bw.close();
br.close();
}
}
6.转换流
OutputStreamWriter
继承自Writer
是字符流通向字节流的桥梁:可以使用指定的字符集将要写入流中的字符编码成字节
构造方法
OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
创建一个使用命名字符集的OutputStreamWriter。
package IO;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class demo18OutputStreamWriter {
public static void main(String[] args) throws IOException {
write_utf8();
write_gbk();
}
/*
通过OutputStreamWriter写一个gbk格式的文件
*/
private static void write_gbk() throws IOException {
//创建 OutputStreamWriter对象,传递字节输出流和指定的编码表名称(不指定默认UTF-8)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src\\IO\\gbk.txt"), "gbk");
osw.write("我爱学习,学习使我快乐!");
osw.flush();
osw.close();
}
private static void write_utf8() throws IOException {
//创建 OutputStreamWriter对象,传递字节输出流和指定的编码表名称(不指定默认UTF-8)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src\\IO\\utf8.txt"), "utf-8");
osw.write("我爱学习,学习使我快乐!");
osw.flush();
osw.close();
}
}
InputStreamReader
继承自Reader
是字节流通向字符流的桥梁,使用指定的字符集读取字节,将其解码为字符。
构造方法
InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。
InputStreamReader(InputStream in, String charsetName)
创建一个使用命名字符集的InputStreamReader。
package IO;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class demo19InputStreamReader {
public static void main(String[] args) throws IOException {
read_utf8();
read_gbk();
}
/*
构造方法中指定的编码要和文件的编码一致
*/
private static void read_gbk() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("src\\IO\\gbk.txt"),"gbk");
int len = 0;
while((len = isr.read()) != -1)
System.out.print((char)len);
isr.close();
}
private static void read_utf8() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("src\\IO\\utf8.txt"),"utf-8");
int len = 0;
while((len = isr.read()) != -1)
System.out.print((char)len);
isr.close();
}
}
示例:文件编码格式转换
import java.io.*;
/*
将GBK格式的文件转化为UTF-8格式的文件
*/
public class demo20转换文件编码格式 {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("src\\IO\\gbk.txt"),"gbk");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src\\IO\\transfer.txt"),"utf-8");
int len = 0;
while((len = isr.read()) != -1){
osw.write(len);
}
osw.close();
isr.close();
}
}
7.序列化与反序列化
概述
序列化
把对象以流的方式写入到文件,叫写对象,也叫对象的序列化
反序列化
把文件中保存的对象,以流的方式读取出来,叫做读对象,也叫对象的反序列化流
ObjectOutputStream
public class ObjectOutputStream
extends OutputStream
implements ObjectOutput,
ObjectStreamConstantsObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
特有的方法:
void writeObject(Object obj)
将指定的对象写入ObjectOutputStream。
注意:
要进行序列化和反序列化的类必须实现Serializable接口,实现了该接口的类才能开启序列化功能
Serializable接口是标记型接口,实现了该接口的类只是被打了个标记,有此标记才能序列化和反序列化
package IO;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*
注意:
要进行序列化和反序列化的类必须实现Serializable接口,实现了该接口的类才能开启序列化功能
Serializable接口是标记型接口,实现了该接口的类只是被打了个标记,有此标记才能序列化和反序列化
*/
public class demo21ObjectOutputStream {
static 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 int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\IO\\student.txt"));
oos.writeObject(new Student("张大炮", 38));
oos.close();
}
}
ObjectInputStream
public class ObjectInputStream
extends InputStream
implements ObjectInput
ObjectOutputStream
和ObjectInputStream
可以分别为与FileOutputStream
和FileInputStream
一起使用的对象图提供持久性存储的应用程序。 ObjectInputStream
用于恢复先前序列化的对象。
特有方法:
Object readObject()
从ObjectInputStream读取一个对象。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class demo22ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\IO\\student.txt"));
Object o = ois.readObject();
ois.close();
System.out.println(o);
}
}
transient关键字
static关键字:
静态优先于非静态加载到内存中
被static修饰的成员变量是不能被序列化的
transient: 瞬态关键字
被transient修饰的成员变量,不能被序列化
InvalidClassException
当序列化运行时检测到类中的以下问题之一时抛出:
1. 类的串行版本与从流中读取的类描述符的类型不匹配
2. 该类包含未知的数据类型
3. 5该类没有可访问的无参数构造函数
在序列化后如果类被修改了,那么反序列化时就会抛出InvalidClassException异常,因为在序列化时编译器会给class文件添加一个序列号,在修改了类之后重新编译时,序列号会发生改变,那么反序列化时序列号不匹配
解决方法:手动给类添加一个序列号
添加static final long seriaVersionUID
字段,为其赋值
集合的序列化
package IO;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import IO.demo21ObjectOutputStream.Student;
public class demo23序列化集合 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
List<Student> list = new ArrayList<>();
list.add(new Student("张大炮", 38));
list.add(new Student("律政先锋", 38));
list.add(new Student("张伟", 38));
list.add(new Student("张益达", 38));
list.add(new Student("snake", 38));
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\IO\\student.txt"));
oos.writeObject(list);
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\IO\\student.txt"));
Object o = ois.readObject();
List<Student> list2 = new ArrayList<>((ArrayList<Student>) o);
System.out.println(list2);
//关闭
ois.close();
oos.close();
}
}
8.打印流
PrintStream
我们平时经常使用的System.out.println();
控制台输出语句,其中的out
其实就是一个PrintStream对象
继承自FileOutputStream
为其他输出流添加了功能,使他们能够方便地打印各种数据值表示形式
特点:
1.只负责数据的输出,不负责数据的读取
2.与其他输出流不同,PrintStream永远不会抛出IOException
3.有特有的方法print,println
构造方法
PrintStream(File file)
使用指定的文件创建一个新的打印流,而不需要自动换行。
PrintStream(File file, String csn)
使用指定的文件和字符集创建新的打印流,而不需要自动换行。
PrintStream(OutputStream out)
创建一个新的打印流。
PrintStream(OutputStream out, boolean autoFlush)
创建一个新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding)
创建一个新的打印流。
PrintStream(String fileName)
使用指定的文件名创建新的打印流,无需自动换行。
PrintStream(String fileName, String csn)
创建一个新的打印流,不需要自动换行,具有指定的文件名和字符集。