特殊操作流
4.特殊操作流
4.1标准输入输出流
System类中有两个静态成员变量:
-
public static final InputStream in :标准输入流
通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
-
public static final PrintStream out:标准输出流
对应于显示输出或由主机环境或用户指定的另一个输出目标
package com.guoba.day1224; import java.io.*; /* 标准输入流 */ public class Demo01 { public static void main(String[] args) throws IOException { // InputStream is = System.in; // //// int by; //// while ((by = is.read())!= -1){ //// System.out.println((char)by); //// } // InputStreamReader isr = new InputStreamReader(is); // // BufferedReader br = new BufferedReader(isr); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入一个字符串:"); String line = br.readLine(); System.out.println("你输入的字符串是:"+line); System.out.println("请输入一个整数:"); int i = Integer.parseInt(br.readLine()); System.out.println("你输入的整数是:"+i); } }
输出语句的本质是:是一个标准输出流
- PrintStream ps = System.out;
- 此类所有的方法,System.out都可以使用
PrintStream ps = System.out; // ps.println("hello"); // ps.println(100); System.out.println("hello"); System.out.println(100);
4.2打印流
打印流分类:
- 字节打印流:PrintStream
- 字符打印流:PrintWiter
打印流特点:
- 只负责输出数据,不负责读取数据
- 有自己特有的方法
字节打印流:
- PrintStream(String fileName):使用指定的文件名创建新的打印流
public static void main(String[] args) throws IOException { PrintStream ps = new PrintStream("基础语法\\1.txt"); ps.write(97); ps.println(97); ps.print(97); ps.close(); }
- 使用继承父类的方法写数据,查看的时候会转码,使用字节特有方法写数据会原样输出
PrintWriter pw =new PrintWriter("基础语法\\pw.txt"); pw.print("hello"); pw.print("\r\n"); pw.print(10); pw.print("\r\n"); pw.close();
布尔值为true时,自动刷新
PrintWriter pw =new PrintWriter(new FileWriter("基础语法\\\\pw.txt"),true); pw.print("hello"); pw.print("\r\n"); pw.print(10); pw.print("\r\n");
案例:复制Java文件(打印流改进版)
package com.guoba.day1224; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; /* 复制java文件(打印流改进版) */ public class Demo03 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("基础语法\\ccccc.txt")); PrintWriter pw = new PrintWriter(new PrintWriter("基础语法\\TwoZero.txt")); String line; while ((line=br.readLine())!= null){ pw.println(line); } pw.close(); br.close(); } }
4.3对象序列化流
》对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
》这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性信息等
》字节序列写到文件中后,相当于在文件中保存了一个对象的信息
》对象反序列化:反之,该字节序列还可以从文件中读回来,重构对象,对他进行反序列化
要实现序列化和反序列化就要使用对象序列化和对象反序列化流:
-
对象序列化流:ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。
- 可以使用ObjectInputStream读取(重构)对象
- 可以通过使用流的文件来实现对象的持久存储。
NotSerializableException:抛出一个需要Serializable接口。
序列化运行时,未实现的类可能会抛出此异常
不实现此接口的类将不会使任何状态序列化或反序列化
Serializable是一个标记接口,实现该类接口,不需要重写任何方法
-
对象反序列化流:ObjectInputStream
-
反序列化前先使用ObjectOutputStream编写原始数据和对象
-
构造方法ObjectOutputStream(InputStream in)
-
Object readObject|():从ObjectInput读取一个对象
package com.guoba.day1224; import com.guoba.day1223.Student; import java.io.*; public class Demo04 { public static void main(String[] args) throws IOException, ClassNotFoundException { //序列化 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("基础语法\\1.txt")); Student s = new Student("社牛",30); oos.writeObject(s);//NotSerializableException oos.close(); } }
//反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("基础语法\\\\1.txt")); Object readObject = ois.readObject(); Student s = (Student)readObject; System.out.println(s.getName()+","+s.getAge());
三个问题:
用序列化流序列化一个对象后修改对象所属文件会不会出问题?
- 会,抛出InvalidClassException异常
如果出问题了,如何解决?
-
给对象所属类加一个serialVersionUID
prvivate static final long serialVersionUID = 42L;
如果一个对象中的某个成员变量的值不想被序列化,如何实现?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与反序列化过程
4.4Properties
概述:是map体系的集合类
可以保存到流中或从流中加载
作为集合的特有方法:
- Object setProperty(String key,String value)
- 设置集合的键和值,都是String类型,底层调用hashtable方法put
- String getProperty(String key)
- 使用此属性列表中指定的键搜索属性
- Set
stringPropertyNames() - 从该属性列表中返回一个不可修改的键集,其中键及其值都是字符串
package com.guoba.day1224; import java.util.Properties; import java.util.Set; public class Demo06 { public static void main(String[] args) { Properties prop = new Properties(); prop.setProperty("itguoba001", "李四"); prop.setProperty("itguoba002", "王五"); Set<String> names = prop.stringPropertyNames(); for (String key : names) { String value = prop.getProperty(key); System.out.println(key + "," + value); } } }
Properties和IO流结合的方法:
-
void load (InputStream inStream)
从输入字节流读取属性列表(键和元素对)
-
void load(Reader reader)
从输入字符流读取属性列表(键和元素对)
-
void stroe(OutputStream out,String comments)
将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流
-
void store(Writer writer,String comments)
将此属性列表写入此Properties表中,以适合使用load(Reader)方法的格式写入输出字符流
package com.guoba.day1227; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Properties; public class Demo01 { public static void main(String[] args) throws IOException{ //mySotre(); myLoad(); } private static void myLoad() throws IOException{ Properties prop = new Properties(); FileReader fr = new FileReader("基础语法\\jiehe_fuben.txt");//文件读取到集合 prop.load(fr); fr.close(); } private static void mySotre() throws IOException { Properties prop = new Properties(); prop.setProperty("itguoba001","叶问"); prop.setProperty("itguoba002","张天志"); prop.setProperty("itguoba003","吴京"); FileWriter fw = new FileWriter("基础语法\\jiehe.txt");//集合保存到文件 prop.store(fw,null); fw.close(); } }
案例:游戏次数
package com.guoba.day1227; import java.util.Random; import java.util.Scanner; public class GuessNumber { public GuessNumber() { } public static void start(){ Random random = new Random(); int number = random.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; } } } }
package com.guoba.day1227; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Properties; /* InputMismatchException 输入不匹配异常,即输入的值数据类型与设置的值数据类型不能匹配 */ public class Demo0_Test { public static void main(String[] args) throws IOException { Properties prop = new Properties(); FileReader fr = new FileReader("基础语法\\game.txt"); prop.load(fr); fr.close(); String count = prop.getProperty("count"); int number = Integer.parseInt(count); if (number >=3){ System.out.println("游戏结束,想玩请充值(https://www.cnblogs.com/guobabiancheng/)"); }else { GuessNumber.start(); number++; prop.setProperty("count",String.valueOf(number)); FileWriter fw = new FileWriter("基础语法\\game.txt"); prop.store(fw,null); fw.close(); } } }
在需要访问的地方创建game.txt内容写count=0