- 一、标准输入流
- 二、标准输出流
- 三、打印流
- 四、字节打印流
- 五、字符打印流
- 六、复制java文件(打印流改进版)
- 七、对象序列化流、对象反序列化流
- 八、应用——游戏次数
- public static final InputStream in
- 通常该流对应于键盘输入或用户指定的另一个输入源
- 自己实现键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- Java提供了一个类实现键盘录入
Scanner sc = new Scanner(System.in);二、标准输出流
- public static final PrintStream out
- 通过该流对应于显示输出或主机环境或用户指定的另一个输出目标
- System.out的本质是一个字节输出流
1、打印流分类
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
2、打印流的特点
- 只负责输出数据,不负责读取数据
- 有自己的特有方法
- PrintStream(String fileName):使用指定的文件名创建新的打印流
- 使用继承父类的方法写数据,查看的时候会转码;使用自己特有方法写数据,查看的数据原样输出
mport java.io.IOException;
import java.io.PrintStream;
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
PrintStream ps = new PrintStream("IO\psd.txt");
//使用继承父类的方法写数据,查看的时候会转码;
ps.write(97);
//使用自己特有方法写数据,查看的数据原样输出
ps.println(97);
}
}
五、字符打印流
1、构造方法
- PrintWriter(String fileName):使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter("IO\pw.txt");
//write方法写入
pw.write("hello");
pw.write("rn");
pw.flush();
pw.write("world");
pw.write("rn");
pw.flush();
pw.write("rn");
pw.flush();
//println方法写入
pw.println("hello");
pw.flush();
pw.println("world");
pw.flush();
pw.println();
pw.flush();
pw.close();
}
}
- PrintWriter(Writer out,boolean autoFlush):创建一个新的PrintWriter,out是字符输出流,autoFlush是一个布尔值,如果为真,则println,printf或format方法将数显输出缓冲区
public class PrintWriterDemo2 {
public static void main(String[] args) throws IOException {
PrintWriter pw = new PrintWriter(new FileWriter("IO\pw.txt"), true);
pw.println("hello");
pw.println("world");
pw.close();
}
}
六、复制java文件(打印流改进版)
需求
把模块目录下的PrintStreamDemo.java复制到模块目录下的Copy.java
思路
- 根据数据源创建字符输入流对象
- 根据目的地创建字符输出流对象
- 读写数据,复制文件
- 释放资源
代码实现
import java.io.*;
public class CopyJavaDemo {
public static void main(String[] args) throws IOException {
//1. 根据数据源创建字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("IO\PrintStreamDemo.java"));
//2. 根据目的地创建字符输出流对象
PrintWriter pw = new PrintWriter(new FileWriter("IO\Copy.java"), true);
//3. 读写数据,复制文件
String line;
while ((line = br.readLine()) != null) {
pw.println(line);
}
//4. 释放资源
br.close();
pw.close();
}
}
七、对象序列化流、对象反序列化流
1、对象序列化、对象反序列化
- 对象序列化:将对象保存在磁盘中,或者在网络中传输对象。这种机制使用一个字节序列表示一个对象,该字节序列包括:对象的类型、对象的数据和对象中存储的属性等信息。
- 字节序列写道文件之后,相当于文件中持久保存了一个对象的信息。
- 反之,该字节序列还可以从文件中读取出来,重构对象,对它进行反序列化
2、对象序列化流
- 对象序列化流:ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream
- 可以使用ObjectInputStream读取(重构)对象
- 可以通过使用流的文件来实现对象的持久存储
- 如果流是网络套接字,则可以在另一个主机上或另一个进程中重构对象
- 构造方法:ObjectOutputStream(OutputStream out),创建一个写入指定的OutputStream的ObjectOutputStream
- 序列化对象的方法:void writeObject(Object obj),将指定的对象写入ObjectOutputStream
- 一个对象要想被序列化,该对象所属的类必须实现Serializable接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
import java.io.Serializable;
public 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 void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO\oos.txt"));
Student s = new Student("zlx", 18);
oos.writeObject(s);
oos.close();
}
}
3、对象反序列化流
- 对象反序列化流:ObjectInputStream
- 对象反序列化先前使用ObjectOutputStream编写的原始数据和对象
- 构造方法:ObjectInputStream(InputStream in),创建从指定的InputStream读取的ObjectInputStream
- 反序列化对象的方法:Object readObject(),从ObjectInputStream读取一个对象
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("IO\oos.txt"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
}
4、serialVersionUID、transient
- 当对象序列化流序列化了一个对象后,如果修改了对象所属的类文件,读取数据会出现问题,抛出InvalidClassException异常。
解决方案:给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42L;
- 如果一个对象中的某个成员变量的值不想被序列化,则给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程。
private transient int age;
5、Properties
- Properties是一个Map体系的集合类
- 可以保存到流中或从流中加载
① Properties作为Map集合的使用
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo1 {
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//存储元素
prop.put("001", "zlx");
prop.put("002", "gtx");
prop.put("003", "hyx");
//遍历集合
Set
② Properties作为Map集合的特有方法
- Object setProperty(String key,String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
- String getProperty(String key):使用此属性列表中指定的键搜索属性
- Set stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo2 {
public static void main(String[] args) {
Properties pro = new Properties();
//Object setProperty(String key,String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
pro.setProperty("001", "zlx");
pro.setProperty("002", "jik");
pro.setProperty("003", "kol");
//String getProperty(String key):使用此属性列表中指定的键搜索属性
System.out.println(pro.getProperty("001"));
System.out.println(pro.getProperty("0011"));
//Set stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
Set spNames = pro.stringPropertyNames();
for (String key : spNames) {
String value = pro.getProperty(key);
System.out.println(key + "," + value);
}
System.out.println(pro);
}
}
③ Properties和IO流相结合的方法
- void load(InputStream inStream):从输入字节流读取属性列表(键和元素对)
- void load(Reader reader):从输入字符流读取属性列表(键和元素对)
- void store(OutputStream out, String comments):将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字符流
- void store(Writer writer, String comments):将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(Reader)方法的格式写入输出字符流
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo3 {
public static void main(String[] args) throws IOException {
//把集合中的数据保存到文件
// myStore();
//把文件中的数据加载到集合
myLoad();
}
private static void myLoad() throws IOException {
Properties pro = new Properties();
FileReader fr = new FileReader("Properties\fw.txt");
pro.load(fr);
fr.close();
System.out.println(pro);
}
private static void myStore() throws IOException {
Properties pro = new Properties();
pro.setProperty("001", "zlx");
pro.setProperty("002", "drf");
pro.setProperty("003", "ftg");
FileWriter fw = new FileWriter("Properties\fw.txt");
pro.store(fw, null);
fw.close();
}
}
八、应用——游戏次数
1、需求
实现猜数字小游戏,只能试玩三次,如果还想玩,提示:游戏试玩已结束,想玩请充值
2、思路
① 写一个游戏类,里边有一个猜数字的小游戏
② 写一个测试类,测试类中有main()方法,main()方法按照下面的步骤完成
- 从文件中读取数据到Properties集合,用load()方法实现
文件已经存在:game.txt
里边有一个数据值:count=0 - 通过Properties集合获取到玩游戏的次数
- 判断次数是否达到三次
如果到了,给提示:游戏试玩已结束,想玩请充值
如果不到,玩游戏,次数+1,重新写回文件,用Properties的store()方法实现
3、代码实现
游戏类
import java.util.Random;
import java.util.Scanner;
public class GuessNumber {
public GuessNumber() {
}
public static void start() {
//使用随机数设置要猜的数字
Random r = new Random();
int number = r.nextInt(100) + 1;
while (true) {
//键盘输入
Scanner sc = new Scanner(System.in);
System.out.println("请输入要猜的数字:");
int guessNumber = sc.nextInt();
//比较数字和系统产生的随机数
if (guessNumber > number) {
System.out.println("你猜的数字" + guessNumber + "大了");
} else if (guessNumber < number) {
System.out.println("你猜的数字" + guessNumber + "小了");
} else {
System.out.println("恭喜你猜中了");
break;
}
}
}
}
测试类
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) throws IOException {
Properties pro = new Properties();
FileReader fr = new FileReader("Properties\game.txt");
pro.load(fr);
String count = pro.getProperty("count");
int number = Integer.parseInt(count);
if (number >= 3) {
System.out.println("游戏试玩结束,想玩请充值");
} else {
GuessNumber.start();
number++;
pro.setProperty("count", String.valueOf(number));
FileWriter fw = new FileWriter("Properties\game.txt");
pro.store(fw, null);
fw.close();
}
}
}



