目录
缓冲流
/*转换流
字符编码:按照某种规则,将字符存储到计算机中
编码:字符A(看得懂)--规则A-》字节B(看不懂)
解码:字节B(看不懂)--规则A-》字符A(看得懂)
字符集(charset):也叫编码表,是一个系统支持的所有字符集合;生活中的文字与计算机中二进制的对应规则。
一套字符集必须至少有一套字符编码;如ASCII字符集、GBK字符集【GBK码表】、Unicode字符集【UTF-8码表】等。
GBK编码:两个字节存储一个中文
UTF-8编码:三个字节存储一个中文【国际】
*/
/*
编码引出的异常:IDEA默认是UTF-8编码,当使用FileReader读取Windows系统【默认是GBK编码】创建的文本文件时,会出现乱码
转换流:字节流通向字符流的桥梁;使用指定码表将字节或字符 进行编码或解码。
public class InputStreamReaderextends Reader
public class OutputStreamWriterextends Writer
java.io.InputStreamReader extends Reader
继承自父类的共性方法
void close()
int read()
int read(char[] cbuf, int offset, int length)
boolean ready()
String getEncoding() 返回此流使用的字符编码的名称。
构造方法:InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader
参数:InputStream in:字节输入流,保存文件中读取到的字节
String character:指定编码表的名称
使用步骤:1、创建InputStreamReader对象,构造方法传参字节输入流和指定编码表名称
2、使用reader(),读取文件
3、释放资源
注意:构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码
* */
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamreader_01 {
public static void main(String[] args) throws IOException {
//read_utf_8();
read_gbk();
}
//读取JBK格式文件
private static void read_gbk() throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IdeaProjects\\java_lianxi\\2.txt"),"gbk");
int len=0;
while((len=isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
//使用InputStreamReader读取utf-8文件
private static void read_utf_8() throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IdeaProjects\\java_lianxi\\1.txt"),"UTF-8");
int len=0;
while((len=isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
}
==
/*java.io.OutputStreamWriter extends Writer
继承自父类的共性方法
void close()
void flush()
void write(char[] cbuf, int off, int len)
void write(int c)
void write(String str, int off, int len)
String getEncoding() 返回此流使用的字符编码的名称。
构造方法
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
* 参数:OutputStream out 字节输出流
String charsetName 指定编码表名称,不区分大小写,默认使用UTF-8
使用步骤:1、创建一个OutputStreamWriter对象,构造方法传递字节输出流和指定的编码表名称
2、使用write();把字符转换为字节,存储到缓冲区中
3、使用flush();把内存缓冲区中的字节刷新到文件中
4、资源释放
* */
import java.io.*;
public class OutputStreamwriter01 {
public static void main(String[] args) throws IOException {
write_utf_8();
write_gbk_1();
}
//使用转换流写gbk格式文件
private static void write_gbk_1() throws IOException {
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IdeaProjects\\java_lianxi\\gbk.txt"),"gbk");
osw.write("你好");
osw.flush();
osw.close();//在IDEA查看是乱码的
}
//使用转换流写utf-8格式文件
private static void write_utf_8() throws IOException {
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IdeaProjects\\java_lianxi\\1.txt"),"utf-8");
osw.write("你好");
osw.flush();
osw.close();
}
}
==
//练习:将GBK编码的文件转换为UTF-8编码的文件
/*分析:1、创建InputStreamReader对象,构造方法传参字节输入流和指定的编码表名称GBK
2、创建OutputStreamWriter对象,构造方法传参字节输出流和指定编码表名称UTF-8
3、使用InputStreamReader对象的方法read();读取文件
4、使用OutputStreamWriter对象的方法writer();把读取的数据写入文件
5、释放资源
*/
public class Lianxi_01 {
public static void main(String[] args) throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IdeaProjects\\java_lianxi\\gbk.txt"),"GBK");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IdeaProjects\\java_lianxi\\utf-8.txt"),"UTF-8");
int len=0;
while((len=isr.read())!=-1){
osw.write(len);
}
osw.close();
isr.close();
}
}
序列化与反序列化
/*序列化 反序列化
序列化:把对象以流【字节流】的形式写入文件中。即 写对象
反序列化:把文件中保存的对象,以流【字节流】的形式读取出来。即 读对象
类通过实现 java.io.Serializable 接口以启用其序列化功能。来实现此接口的类将无法使其任何状态序列化或反序列化
java.io.Serializable 接口也叫标记接口:
注意:1、要实现序列化或反序列化的类,必须实现Serializable接口,就会给类添加一个标记;进行序列化或反序列化时,就会检测类上是否有标记,如果没有,抛出NotSerializableException异常
2、必须实现类对应的class文件
3、可序列化的类可以声明序列号来避免InvalidClassException异常【序列号不匹配异常】
声明格式:private static final long serialVersion=声明的序列号L;
反序列化:public class ObjectInputStreamextends InputStream
构造方法:ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
特有成员方法:Object readObject() 从 ObjectInputStream 读取对象。
序列化:public class ObjectOutputStreamextends OutputStream
构造方法:ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。
特有成员方法: void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
*瞬态关键字:transient【序列化反序列化对象时,不想读或写对象的某一部分,可以使用transinet关键字修饰】
static:静态关键字
静态优先于非静态进入内存(静态优先于对象进入内存);
注意:被static修饰的成员变量,不能被序列化
transient:瞬态关键字
注意:被transient修饰的成员变量,不能被序列化
*
*/
==
import java.io.Serializable;
public class Person implements Serializable {//必须实现此接口
private static final serialVersion=1L;
private String name;
//private static String name;
//private transient String name;
private int 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 Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//序列化
public class Demo01ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("E:\\IdeaProjects\\java_lianxi\\person.txt"));
Object o = ois.readObject();
ois.close();
System.out.println(o);//Person{name='禾苗', age=21}
Person p=(Person)o;
System.out.println(p.getName()+p.getAge());//禾苗21
}
}
//反序列化
public class ObjectOutputStream01 {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("E:\\IdeaProjects\\java_lianxi\\person.txt"));
oos.writeObject(new Person("禾苗",21));
oos.close();
}
}
/*练习:序列化集合
文件存储多个对象,可以吧多个对象存储到一个集合中,对集合进行序列化和反序列化。
分析:1、定义一个存储对象的集合ArrayList
2、向集合中存储对象
3、创建序列化流ObjectOutputStream对象
4、使用writeObject(),向集合写对象
5、创建一个反序列化流ObjectInputStream对象
6、使用readObject(),在集合里读对象
7、把Object类型集合转换为ArrayList集合
8、遍历ArrayList集合
9、释放资源
* */
import java.io.*;
import java.util.ArrayList;
public class DemoText {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ArrayList<Person> list=new ArrayList<>();
list.add(new Person("张三",18));
list.add(new Person("李四",19));
list.add(new Person("王五",20));
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("E:\\IdeaProjects\\java_lianxi\\list.txt"));
oos.writeObject(list);
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("E:\\IdeaProjects\\java_lianxi\\list.txt"));
Object o = ois.readObject();
//7
ArrayList<Person> list2=(ArrayList<Person>) o;
//8
for (Person p : list2) {
System.out.println(p);
}
//9
ois.close();
oos.close();
}
}
打印流
/* 打印流:java.io.PrintStream extends FilterOutputStream 使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。
* 特点:1、只负责数据的输出
* 2、与其他输出流不同,PrintStream 永远不会抛出 IOException
* 3、特有方法void print(任意类型),
* void println(任意类型)
* 构造方法:PrintStream(File file) 输出目的地是一个文件
* PrintStream(OutputStream out) 目的地是一个字节输出流
* PrintStream(String fileName) 目的地是一个文件路径
* 注意:如果使用继承父类的方法write()写数据,那么查看数据时会查询编码表
* 如果使用特有方法println()写数据,数据原样输出
* 可以改变输出语句目的地(打印流的流向):输出语句默认在控制台为目的地
* 使用 java.lang.System
* static void setOut(PrintStream out) 改变输出语句目的地改变为参数传递的打印流目的地
*
PrintWriter
public PrintWriter(String fileName,
String csn) throws FileNotFoundException,
参数:
fileName - 用作此 writer 目标的文件名称。如果存在该文件,则将其大小截取为零;否则,创建一个新文件。将输出写入文件中,并对其进行缓冲处理。
csn - 受支持的字符集的名称
* */
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Demo01PrintStream {
public static void main(String[] args) throws FileNotFoundException {
//PrintStream ps=new PrintStream("E:\\IdeaProjects\\java_lianxi\\1.txt");
System.out.println("目的地原本是控制台");
PrintStream ps=new PrintStream("E:\\IdeaProjects\\java_lianxi\\1.txt");
System.setOut(ps);//将目的地改为打印流目的地
System.out.print("目的地改变");
ps.write(97);
ps.println(97);
ps.close();//控制台输出:目的地原本是控制台
//1.txt里: 目的地改变a97a97
}
}