目录
- 1、转换流
- 1.1 转换流分类:
- 1.2 转换流的作用
- (1)按照指定的字符编码读写操作:
- (2)将字节流转换为字符流进行操作:
- 2、序列化流
- 2.1 序列化的基本使用:
- 2.2 序列化的操作流程:
- 2.3 总结
- 2.4 案例:
- 3、打印流
- 3.1 打印流概念
- 3.2 打印流的使用
- (1)PrintStream打印流:
- (2)PrintWriter打印流:
- (3)总结:
- 4、Properties集合
- 4.1 Properties介绍
- 4.2 作为集合的使用:
- 4.3 和IO有关的方法:
- 4.4 总结
1、转换流
1.1 转换流分类:
1.2 转换流的作用
(1)按照指定的字符编码读写操作:
(2)将字节流转换为字符流进行操作:
package com.itheima.change;
import java.io.*;
public class ChangeStreamDemo1 {
/**
* 转换流按照指定的字符编码读写
*
* 构造方法:
* InputStreamReader(InputStream in, String CharsetName)
* OutputStreamWriter(OutputStream out, String CharsetName)
*/
public static void main(String[] args) throws IOException {
//read();
write();
}
private static void write() throws IOException {
//按照gbk编码方式写入内容,同时是追加写入
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\c.txt", true), "gbk");
osw.write("哈哈");
osw.close();
}
private static void read() throws IOException {
//按照gbk编码方式读取内容
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\stu.txt"), "gbk");
int i;
while ((i = isr.read()) != -1){
System.out.println((char)i);
}
isr.close();
}
}
2、序列化流
2.1 序列化的基本使用:
package com.itheima.serialization;
import java.io.*;
public class SerializationDemo1 {
/**
* 序列化流读写对象
* 序列化: 将对象写出到文件
* public ObjectOutputStream(OutputStream out)
* 反序列化:从文件中将对象读取到程序
* public ObjectInputStream(InputStream in)
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
//writeObject();
readObject();
}
private static void readObject() throws IOException, ClassNotFoundException {
//反序列化,即从文件中将对象读取到程序
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("stu.txt"));
Object o = ois.readObject();
System.out.println(o);
//关闭流
ois.close();
}
private static void writeObject() throws IOException {
//创建一个对象
Student s = new Student("张三", 23);
//将对象序列化,即写入到文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.txt"));
oos.writeObject(s);//调用这个方式之前,序列化的对象需要实现Serializable接口
//关闭流
oos.close();
}
}
2.2 序列化的操作流程:
上述流程解释如下:
1、当我们要序列化对象时,首先需要对象实现Serializable
接口,实现了这个接口之后,其实就会给这个对象生成一个序列化ID;
2、然后调用writeObject()
方法进行序列化时,除了将对象的内容保存到文件之外,还会将这个序列化ID写入;
3、当我们调用readObject()
方法进行反序列化时,会对比文件里的序列ID是否与当前程序中的对象序列化ID相等,如果相等则反序列化成功,如果不相等,则报错。
那有人就要问了,怎么会不相等呢?试想一下,如果序列化后,我们将对象增加属性或方法,那么序列化ID肯定就不相等了。
如何解决这个问题呢?
答:当我们标记一个对象需要序列化时(实现Serializable
接口就是这个标记),手动指定序列化ID,那么就能解决上述问题,如下这样即可:
手动指定的序列化ID,我们可以借助idea工具实现,设置如下:
然后在idea中,提示快捷键alt+enter即可,或者点击提示也行。具体可以参考:使用idea自动生成序列化ID全过程
如果某一个属性不想被序列化,则需要使用
transient
关键字修饰,如下所示:
2.3 总结
2.4 案例:
package com.itheima.serialization;
import java.io.*;
public class SerializationDemo2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1、定义三个对象
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
//2、定义输出序列化流,并执行序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("序列化.txt", true));
oos.writeObject(s1);
oos.writeObject(s2);
oos.writeObject(s3);
oos.close();
//3、定义反序列化流,并执行反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("序列化.txt"));
while (true){
try {
//readObject()方法读取到末尾后,如果继续读取,则会报IOException异常
Object o = ois.readObject();
System.out.println(o);
}catch (IOException e){
break;
}
}
ois.close();
}
}
上述代码的写法,多个对象就做多少次序列化,同理,那要反序列化也需要多次。其实一般情况下,我们可以将对象存入一个集合中,然后只执行一次序列化,一次反序列化即可,如下代码:
package com.itheima.serialization;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class SerializationDemo3 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1、定义三个对象
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 23));
list.add(new Student("李四", 24));
list.add(new Student("王五", 25));
//2、定义输出序列化流,并执行序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("序列化2.txt", true));
oos.writeObject(list);//只执行一次序列化,因为List也实现了Serializable接口
oos.close();
//3、定义反序列化流,并执行反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("序列化2.txt"));
List<Student> list1 = (List<Student>)ois.readObject();//只执行一次
ois.close();
//4、遍历打印
for (Student student : list1) {
System.out.println(student);
}
}
}
3、打印流
3.1 打印流概念
package com.itheima.print;
import java.io.PrintStream;
public class PrintDemo1 {
/**
* System.out.println() 打印语句的细节
*/
public static void main(String[] args) {
//1、获取打印流
PrintStream out = System.out;
//2、执行打印
out.println("你好");
//简化如下
System.out.println("你好");
}
}
3.2 打印流的使用
(1)PrintStream打印流:
标准打印流是向控制台输出,那么能不能往文件写入呢?为了解决这个问题,我们接着看,下面是打印流的三个构造方法,看例子怎么使用:
package com.itheima.print;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintDemo2 {
/**
* PrintStream基本使用
* 1、创建对象关联文件
* public PrintStream(OutputStream os)
* public PrintStream(File f)
* public PrintStream(File f, String csn):第二个参数为指定的编码格式
* public PrintStream(String filepath)
* public PrintStream(String filepath, String csn):第二个参数为指定的编码格式
* 2、写出方法
* write(): 写出也给字节,不建议使用,无法原样写入
* print(): 原样写入数据,无换行
* println(): 原样写入数据,带有换行
*/
public static void main(String[] args) throws Exception {
//method1();
//method2();
method3();
}
/**
* 不带编码格式的打印流
*/
private static void method1() throws Exception {
//1、定义打印流
PrintStream ps = new PrintStream("打印流.txt");
//2、写入文件
ps.write(97);//不能保证原样写入,不建议使用
ps.println(97);//原样写入数据,带有换行
ps.print(97);//原样写入数据,无换行
ps.close();
}
/**
* 指定编码格式的打印流
*/
private static void method2() throws Exception {
PrintStream ps = new PrintStream("打印流.txt", "utf-8");
ps.println("你好啊");
}
/**
* 追加写入
*/
private static void method3() throws FileNotFoundException {
PrintStream ps = new PrintStream(new FileOutputStream("打印流.txt", true));
ps.println("追加写入了一行");
ps.println("追加写入了二行");
ps.println("追加写入了三行");
}
}
(2)PrintWriter打印流:
package com.itheima.print;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriteDemo1 {
/**
* PrintWrite的使用
*/
public static void main(String[] args) throws IOException {
//1、基本使用
PrintWriter pw = new PrintWriter("F.txt");
pw.println("你好");
pw.flush();
pw.close();
//2、自动刷新的使用方法:在构造方法里第二个参数写true,不调用flush或close方法,也会自动刷新
// 注:只对println方法管用
PrintWriter pw2 = new PrintWriter(new FileWriter("G.txt"), true);
pw2.println("哈哈哈");
}
}
(3)总结:
4、Properties集合
4.1 Properties介绍
4.2 作为集合的使用:
package com.itheima.properties;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo1 {
/**
* Properties作为集合的使用:
* Object setProperty(String key, String value):类似Map集合的put方法
* String getProperty(String key):类似Map集合的get方法
* Set<String> stringPropertyNames():类似Map集合的keySet方法
*/
public static void main(String[] args) {
Properties p = new Properties();
//1、set方法
p.setProperty("username", "admin");
p.setProperty("password", "1234");
System.out.println(p);//{password=1234, username=admin}
//2、get方法
Object username = p.get("username");
Object password = p.get("password");
System.out.println(username);//admin
System.out.println(password);//1234
//3、keySet方法:用于获取key组成的集合
Set<String> keySet = p.stringPropertyNames();
for (String s : keySet) {
System.out.println(s + "------" + p.get(s));
}
}
}
4.3 和IO有关的方法:
package com.itheima.properties;
import java.io.*;
import java.util.Properties;
public class PropertiesDemo2 {
/**
* Properties 和 IO 有关的方法
* void load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)
* void load(Reader reader) 从输入字符流读取属性列表(键和元素对)
* void store(OutputStream outStream, String comments) 将集合的键值对写出到文件(字节流),comments是注释
* void store(Writer writer, String comments) 将集合的键值对写出到文件(字符流),comments是注释
*/
public static void main(String[] args) throws IOException {
// storeMethod();
Properties prop = new Properties();
//load()方法:从文件将内容读取到流中
// FileInputStream fis = new FileInputStream("config.properties");//字节流
FileReader fis = new FileReader("config.properties");//字符流
prop.load(fis);
fis.close();
System.out.println(prop);//{password=1234, username=admin}
}
private static void storeMethod() throws IOException {
Properties prop = new Properties();
prop.setProperty("username", "admin");
prop.setProperty("password", "1234");
//store()方法:将内容写入文件
// FileOutputStream fos = new FileOutputStream("config.properties");//字节流
FileWriter fos = new FileWriter("config.properties");//字符流
prop.store(fos, "我是注释,不想写的话可以写null");
fos.close();
}
}