转换流
转换流分为两个:
- OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。
- InputStreamReader:是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符
OutputStreamWriter
java.io.OutputStreamWriter extends Writer
OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。
继承自父类的共性方法:
void close() 关闭此流,但要先刷新它。
void flush() 刷新此流。
void write(char[] cbuf) 写入字符数组。
void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
void write(int c) 写入单个字符。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分。
构造方法:
OutputStreamWriter(OutputStream out)创建使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out,String charsetName)创建使用指定字符集的OutputStreamWriter
参数:
OutputStream out:字节输出流,可以用来写转换后的字节到文件中
String charsetName:指定的编码表名称,不区分大小,不写默认是UTF-8
使用步骤:
1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
2.使用OutputStreamWriter对象中的方法write,把字符转化为字节存储缓冲区中(编码)
3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
4.释放资源
public class DemoOutputStreamWriter {
public static void main(String[] args) throws IOException {
writer_utf_8();
}
private static void writer_utf_8() throws IOException {
//1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaProjects\\basic-code\\10Stream\\src\\c.txt"),"utf-8");
//不指定编码表,默认utf-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaProjects\\basic-code\\10Stream\\src\\c.txt"),"GbK");
//2.使用OutputStreamWriter对象中的方法write,把字符转化为字节存储缓冲区中(编码)
osw.write("你好啊");
//3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
osw.flush();
osw.close();
}
}
InputStreamReader
java.io.InputStreamReader extends Reader
InputStreamReader:是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符
共性的成员方法:
int read()读取单个字符并返回
int read(char[] chars)一次读取多个字符,将字符读入数组
void close()关闭该流并释放与之关联的所有资源
构造方法:
InputStreamReader(InputStream in)创建一个使用默认字符集的InputStreamReader
InputStreamReader(InputStream in,String charsetName)创建使用指定字符集的InputStreamReader
参数:
InputStream in:字节输入流,用来读取文件中保存的字节
String charsetName:指定的编码表名称,不区分大小写,可以是utf-8,GBK,Unicode,不指定默认是utf-8
使用步骤:
1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
2.使用InputStreamReader对象中的方法read读取文件
3.释放资源
注意事项:
构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码
public class DemoInputStreamReader {
public static void main(String[] args) throws IOException {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\IdeaProjects\\basic-code\\10Stream\\src\\c.txt"),"utf-8");
// 2.使用InputStreamReader对象中的方法read读取文件
int len = 0;
while ((len = isr.read())!= -1){
System.out.println((char) len);
}
isr.close();
}
}
练习
练习:转换文件编码
将GBK编码的文件,转化为UTF-8编码的文件
分析:
- 1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
- 2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
- 3.使用InputStreamReader对象中的方法read读取文件
- 4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
- 5.释放资源
public class Test {
public static void main(String[] args) throws IOException {
// 1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\IdeaProjects\\basic-code\\10Stream\\src\\c.txt"),"GBK");
// 2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaProjects\\basic-code\\10Stream\\src\\b.txt"),"utf-8");
int len = 0;
// 3.使用InputStreamReader对象中的方法read读取文件
while ((len = isr.read()) != -1){
// 4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
osw.write(len);
}
// 5.释放资源
osw.close();
isr.close();
}
}
流的序列化、反序列化
序列化:把对象以流的方式,写入到文件中保存,叫写对象,也叫对象的序列化
反序列化:把文件中保存的对象,以流的方式读取出来,也叫读对象,叫对象的反序列化
流的序列化
java.io.ObjectOutputStream extends OutputStream
ObjectOutputStream:对象的序列化流
作用:把对象以流的方式写入到文件中保存
构造方法:
ObjectOutputStream(OutputStream out)创建写入指定 OutputStream 的ObjectOutputStream
参数:
OutputStream out:字节输出流
特有的成员方法:
void writeObject(Object obj) 将指定的对象写入ObjectOutputStream
使用步骤:
1.创建ObjectOutputStream对象,构造方法中传递字节输出流
2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
3.释放资源
public class DemoObjectOutputStream {
public static void main(String[] args) throws IOException {
// 1.创建ObjectOutputStream对象,构造方法中传递字节输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\IdeaProjects\\basic-code\\10Stream\\d.txt"));
// 2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
oos.writeObject(new Person("小红",21));
//3.释放资源
oos.close();
}
}
流的反序列化
java.io.ObjectInputStream extends InputStream
ObjectInputStream对象的反序列化流
作用:把文件中保存的对象,以流的方式读取出来使用
构造方法:
ObjectInputStream(InputStream in)创建从指定InputStream读取的ObjectInputStream
参数:
InputStream in:字节输入流
特有的成员方法
Object readObject() 从ObjectInputStream读取对象
使用步骤:
1.创建ObjectInputStream对象,构造方法中传递字节输入流
2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
3.释放资源
4.使用读取出来的对象(打印)
readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)
当不存在对象的class文件时抛出此异常
反序列化的前提:
1.类必须实现Serializable
2.必须存在类对应的class文件
public class DemoObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 1.创建ObjectInputStream对象,构造方法中传递字节输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\IdeaProjects\\basic-code\\10Stream\\d.txt"));
// 2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
Object o = ois.readObject();
//3.释放资源
ois.close();
System.out.println(o);
}
}
练习
练习:序列化集合
当我们想在文件中保存多个对象的时候
可以把多个对象存储到一个集合中
对集合进序列化和反序列化
分析:
1.定义一个存储Person对象的ArrayList集合
2.往ArrayList集合中存储Person对象
3.创建一个序列化流ObjectOutputStream对象
4.使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化、
5.创建一个反序列化ObjectInputStream对象
6.使用ObjectInputStream对象中的方法readObject读取文件中保存的集合
7.把Object类型的集合转化为ArrayList类型
8.遍历ArrayList集合
9.释放资源
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.定义一个存储Person对象的ArrayList集合
ArrayList<Person> list = new ArrayList<>();
//2.往ArrayList集合中存储Person对象
list.add(new Person("小魏",22));
list.add(new Person("小梁",19));
list.add(new Person("小王",20));
//3.创建一个序列化流ObjectOutputStream对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\IdeaProjects\\basic-code\\10Stream\\e.txt"));
oos.writeObject(list);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\IdeaProjects\\basic-code\\10Stream\\e.txt"));
Object o = ois.readObject();
//7.把Object类型的集合转化为ArrayList类型
ArrayList<Person> list1 = (ArrayList<Person>)o;
for (Person p : list1) {
System.out.println(p);
}
oos.close();
ois.close();
}
}
打印流
java.io.PrintStream:打印流
PrintStream为其他输出流添加了功能,使他们能够方便的打印各种数据值表示形式
PrintStream特点:
1.只负责数据的输出,不负责数据的读取
2.与其他输出流不同,PrintStream永远不会抛出IOException
3.有特有的方法,print,println
void print(任意类型的值)
void println(任意类型的值并换行)
构造方法:
PrintStream(File file)输出的目的地是一个文件
PrintStream(OutputStream out)输出的目的地是一个字节输出流
PrintStream(String fileName)输出的目的地是一个文件路径
PrintStream extends OutputStream
继承自父类的方法:
public void close() 关闭此输出流并释放与此流相关的任何系统资源
public void flush() 刷新此输出流并强制任何缓冲的输出字节被写出
void write(byte[] b) 将 b.length 个字节从指定的字节数组写入此输出流。
void write(byte[] b, int off, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b) 将指定的字节写入此输出流。
注意:
如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97--a
如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97--97
public class DemoPrintStream {
public static void main(String[] args) throws FileNotFoundException {
//创建打印流PrintStream对象,构造方法中绑定要输出的目的地
PrintStream ps = new PrintStream("D:\\IdeaProjects\\basic-code\\10Stream\\f.txt");
//如果使用继承自父类的writer方法写数据,那么查看数据的时候会查询编码表
ps.write(97);
//如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97--97
ps.println(97);
ps.println(8.8);
ps.println(true);
ps.close();
}
}