1.转换流-概念
字符流中和编码解码问题相关的两个类
-
InputStreamReader: 是从字节流到字符流的桥梁,父类是Reader
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
-
OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
转换流读写数据
- 构造方法
方法名 | 说明 |
---|---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
要点
转换流 :
字节流--------->字符流, 桥梁
InputStreamReader(InputStream in);
字符流---------->字节流 桥梁
OutputStreamWriter(OutputStream out)
===========================================================
读取
读取字符,一般使用 FileReader,或 BufferedReader
InputStream byte
读取 char,来源的字节输入流 InputStream 已确定! new InputStreamReader(InputStream)
======================================
写入
写入字符,字符串,一般使用 FileWriter 或 BufferedWriter
OutputStream, byte,byte[]
写入 char,String, 目标地的字节输出流 OutputStream 已确定! new OutputStreamWriter(OutputStream)
2.转换流-指定编码读写
public class ConvertedDemo1 {
public static void main(String[] args) throws IOException {
//method1();
//method2();
//在JDK11之后,字符流新推出了一个构造,也可以指定编码表
FileReader fr = new FileReader("C:\\Users\\apple\\Desktop\\a.txt", Charset.forName("gbk"));
int ch;
while ((ch = fr.read())!=-1){
System.out.println((char) ch);
}
fr.close();
}
private static void method2() throws IOException {
//如何解决乱码现象
//文件是什么码表,那么咱们就必须使用什么码表去读取.
//我们就要指定使用GBK码表去读取文件.
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\apple\\Desktop\\a.txt"),"gbk");
int ch;
while((ch = isr.read())!=-1){
System.out.println((char) ch);
}
isr.close();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\apple\\Desktop\\b.txt"),"UTF-8");
osw.write("我爱学习,谁也别打扰我");
osw.close();
}
}
要点
1. FileReader,FileWriter可以指定编码读写(注意编译器版本,jdk11)
FileReader fr = new FileReader("a.txt",Charset.forName("gbk"));
FileWriter fw = new FileWriter("b.txt",Charset.forName("utf-8"));
2. OutputStreamWriter InputStreamReader 转换流,字节流---通往--字符流的桥梁
如果已经存在 InputStream,想读取字符,可以使用 InputStreamReader(InputStream)
如果已经存在 OutputStream,想写入字符,字符串,可以使用 OutputStreamWriter(OutputStream)
//代码示例:
//关联到键盘输入的字节输入流
InputStream in = System.in;
// int c = in.read(); //只能读字节
// System.out.println((char) c);
InputStreamReader isr = new InputStreamReader(in);
int c = isr.read(); //可以读取字符
System.out.println((char) c);
需求:使用BufferedReader,读取键盘录入,一次读取一行,并打印
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s ;
while ((s = br.readLine()) != null {
if ("end".equals(s)) {
break;
}
System.out.println(s);
}
-----------------------------------------------------------------------------
//字节输出流已存在
FileOutputStream fos = new FileOutputStream("c:\\1.txt");
//我想写入字符,字符串,可以使用转换流
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write("hello中国");
osw.close();
3.对象操作流-基本特点
可以把对象以字节的形式写到本地文件,直接打开文件,显示的是乱码,需要再次用对象操作流读到内存中。
要点
序列化:将对象转成字节序列, 可以保存到磁盘,也可以发送到网络
反序列化:读取字节序列,返回一个对象(字节序列可以来自文件,也可以来自网络)
4.对象操作流-序列化
-
对象序列化介绍
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
-
对象序列化流: ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
- 构造方法
方法名 | 说明 |
---|---|
ObjectOutputStream(OutputStream out) | 创建一个写入指定的OutputStream的ObjectOutputStream |
- 序列化对象的方法
方法名 | 说明 |
---|---|
void writeObject(Object obj) | 将指定的对象写入ObjectOutputStream |
-
示例代码
学生类
public class Student {
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
//创建对象
Student s = new Student("bibabo",30);
//void writeObject(Object obj):将指定的对象写入ObjectOutputStream
oos.writeObject(s);
//释放资源
oos.close();
}
}
注意事项
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
要点
掌握概念
对象序列化:
将对象转成字节序列 (保存在磁盘中,或通过网络传输)
ObjectOutputStream(OutputStream)
对象反序列化:
读取字节序列,返回一个对象(字节序列可以来自于文件,也可以来自于网络)
序列化的步骤
1.创建 ObjectOutputStream(OutputStream)
2.创建对象(学生对象)
3.writeObject(stu);
4.关闭流
注意:
1.被序列化的对象所在的类必须实现 Serializable
5.对象操作流-反序列化
-
对象反序列化流: ObjectInputStream
-
ObjectInputStream反序列化先前使用
ObjectOutputStream编写的原始数据和对象
-
ObjectInputStream反序列化先前使用
- 构造方法
方法名 | 说明 |
---|---|
ObjectInputStream(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
- 反序列化对象的方法
方法名 | 说明 |
---|---|
Object readObject() | 从ObjectInputStream读取一个对象 |
- 示例代码
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
}
6.对象操作流-两个注意点
7.序列化小结:
//序列化流(将对象---二进制)
ObjectOutputStream(OutputStream)
void writeObject(Object)
//反序列化流(读取二进制---->返回对象)
ObjectInputStream(InputStream)
Object readObject()
注意:
1.要序列化的类必须实现Serializable接口
2.private static final long serialVersionUID = 13212312L;
3.private transient int chinese; //瞬时状态,不会保存到文件,比较安全
问题:如何序列化多个对象,并反序列化?
1. 死循环,try catch(EOFException ex) {barak;}
2. 添加元素到集合,序列化集合(推荐)
8.Properties-概述
9.Properties-作为Map集合的基本使用
-
Properties介绍
- 是一个Map体系的集合类
- Properties可以保存到流中或者从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
- Properties基本使用
public class PropertiesDemo01 {
public static void main(String[] args) {
//创建集合对象
// Properties<String,String> prop = new Properties<String,String>(); //错误
Properties prop = new Properties();
//存储元素
prop.put("001", "bibabo");
prop.put("002", "bibowen");
prop.put("003", "simade");
//遍历集合
Set<Object> keySet = prop.keySet();
for (Object key : keySet) {
Object value = prop.get(key);
System.out.println(key + "," + value);
}
}
}
10.Properties-特有方法
- 特有方法
方法名 | 说明 |
---|---|
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
- 代码示例
public class PropertiesDemo02 {
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//Object setProperty(String key, String value):设置集合的键和值,都是String类型
prop.setProperty("001", "bibabo");
prop.setProperty("002", "bibowen");
prop.setProperty("003", "simade");
//String getProperty(String key):使用此属性列表中指定的键搜索属性
// System.out.println(prop.getProperty("001"));
// System.out.println(prop.getProperty("0011"));
// 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);
}
}
}
11.Properties-load
- 和IO流结合的方法
方法名 | 说明 |
---|---|
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
- 代码示例
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("myOtherStream\\fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
}
12.Properties-store
代码示例
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("001", "bibabo");
prop.setProperty("002", "bibowen");
prop.setProperty("003", "simade");
//void store(Writer writer, String comments);
FileWriter fw = new FileWriter("myOtherStream\\fw.txt");
prop.store(fw,null);
fw.close();
}
要点
void store(Writer/OutputStream,"注释说明"): 保存内容到文件
注:load方法使用更多。 一般很少写入文件,都是读取properties文件。
13.IO流小结
1.体系
2.构造
3.步骤(1.创建流, 2.操作流, 3.关闭流)
字节流
InputStream(抽象)
FileInputStream(String/File)
BufferedInputStream(InputStream): 缓冲流= 基础流+缓冲区
int read()
int read(byte[])
OutputStream(抽象)
FileOutputStream(String/File)
BufferedOutputStream(OutputStream)缓冲流= 基础流+缓冲区
write(int)
write(byte[])
write(byte[],index,len)
=======================================================================================
字符流=字节流+编码表
Reader(抽象)
FileReader(String/File,CharSet.forName("gbk"))
BufferedReader(Reader)
String readLine():一次读取一行,读取不到返回null
InputStreamReader(InputStream):转换流,把字节流转成字符流
int read() 读一个字符
int read(char[])读一个字符数组
Writer(抽象)
FileWriter(String/File,CharSet.forName("gbk"))
BufferedWriter(Writer)
void newLine(); 写入换行符
OutputStreamWriter(OutputStream):转换流,把字符流转成字节流
write(int)
write(char[])
write(String)
3种复制(1.字节流复制,一次一个字节, 2.字节流复制,一次一个字节数组 3. 高效字符流复制文本文件,一次一行)
14.序列化流
序列化: 将对象转成字节序列,保存到磁盘或发送到网络
反序列化: 读取字节序列,返回一个对象
序列化流
ObjectOutputStream(OutputStream)
writeObject(Object)
反序列化流
ObjectInputStream(InputStream)
Object readObject()
注意事项:
1.要被序列化的对象所在类必须实现 Serializable接口(标记型接口)
2. 防止反序列化时,修改类导致的异常,可以添加序列化版本号
private static final long serialVersionUID = 42L;
3.不想被序列化的字段可以使用transient关键字
15.Properties小结
作用: 最常用来读取key=value格式的properties配置文件
构造:
Properties()
添加
setProperty(String,String)
获取
String getProperty(Stirng key)
遍历
Set<String> stringPropertyNames()
保存集合到文件
store(OutputSteam/Writer, ”说明信息”);
从文件中加载内容到集合
load(InputStream/Reader);
有了HashMap,Properties集合的意义?
Properties主要是用来读取/写入properties配置文件的.
Properties还可直接从流中加载, HashMap不行.
版权声明:本文为Nusret原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。