1、标准输入输出流
System类中有两个静态的成员变量:
- public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
- public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
自己实现键盘录入数据:
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
写起来太麻烦,Java提供了一个类实现键盘录入
- Scanner sc = new Scanner(System.in);
package OtherStream_01;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
/*
public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
*/
public class SystemInDemo {
public static void main(String[] args) throws IOException {
//public static final InputStream in:标准输入流。
// InputStream is = System.in;
// int by;
// while((by=is.read())!=-1){
// System.out.print((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);
//自己实现键盘录入数据太麻烦,Java提供了一个类供我们使用
Scanner sc = new Scanner(System.in);
}
}
输出语句的本质:是一个标准的输出流
- PrintStream ps = System.out;
- PrintStream类有的方法,System.out都可以使用
package OtherStream_01;
import java.io.PrintStream;
/*
public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
*/
public class SystemOutDemo {
public static void main(String[] args) {
//public static final PrintStream out:标准输出流。
PrintStream ps = System.out;
//能够方便的打印各种数据值
// ps.print("hello");
// ps.print(100);
// ps.println("hello");
// ps.println(100);
//System.out的本质是一个字节输出流
System.out.println("hello");
System.out.println(100);
System.out.println();
// System.out.print();//必须有参数
}
}
2、打印流
打印流分类:
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
打印流的特点:
- 只负责输出数据,不负责读取数据
- 有自己的特有方法
字节打印流
- PrintStream(String fileName):使用指定的文件名创建新的打印流
- 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
字符打印流PrintWriter的构造方法:
方法名 | 说明 |
PrintWriter(String fileName) | 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新 |
PrintWriter(Writer out,boolean autoFlush) | 创建一个新的PrintWriter
|
3、对象序列化流
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象类型、对象的数据和对象中存储的属性等信息;字节序列写到文件之后,相当于文件中持久保存了一个对象的信息 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:
- 对象序列化流:ObjectOutputStream
- 对象反序列化流:ObjectInputStream
对象序列化流:ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
构造方法:
- ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
序列化对象的方法:
- void writerObject(Object obj):将指定的对象写入ObjectOutputStream
注意:
- 一个对象要想被序列化,该对象所属的类必须实现Serializable接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
package OtherStream_03;
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;
}
}
-------------------------------------------------
package OtherStream_03;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/*
构造方法:
ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
序列化对象的方法:
void writerObject(Object obj):将指定的对象写入ObjectOutputStream
NotSerializableException:抛出一个实例需要一个Serializable接口。序列化运行时或实例的类可能会抛出此异常
类的序列化由实现java.io.Serializable接口的类启用。不实现此接口的类将不会使任何状态序列化或反序列化
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Document\\Java\\myOtherStream\\oos.txt"));
//创建对象
Student s = new Student("张三", 22);
//void writerObject(Object obj):将指定的对象写入ObjectOutputStream
oos.writeObject(s);
//释放资源
oos.close();
}
}
对象反序列化流:ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
构造方法:
- ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
反序列化对象的方法:
- Object readObject():从ObjectInputStream读取一个对象
package OtherStream_03;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.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("D:\\Document\\Java\\myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
//向下转型
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
//释放资源
ois.close();
}
}
用对象序列化流序列了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题?
- 会出问题,抛出InvalidClassException异常
如果出问题了,如何解决?
- 给对象所属的类加一个serivalVersionUID
- private static final long serivalVersionUID = 42L;
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
package OtherStream_03;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
// private int age;
private transient 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 +
// '}';
// }
}
-----------------------------------------------------
package OtherStream_03;
import java.io.*;
/*
用对象序列化流序列了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题?
java.io.InvalidClassException:
当序列化运行时检测到类中的以下问题之一时抛出:
类的串行版本与从流中读取的类描述符的类型不匹配
该类包含未知的数据类型
该类没有可访问的无参构造函数
OtherStream_03.Student; local class incompatible:
stream classdesc serialVersionUID = -3365970708951366316,
local class serialVersionUID = 541822342932242746
如果出问题了,如何解决?
给对象所属的类加一个值:private static final long serialVersionUID = 42L;
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
private transient int age;
*/
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//write();
read();
}
//反序列化
private static void read() throws IOException, ClassNotFoundException {
//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Document\\Java\\myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
//向下转型
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
//释放资源
ois.close();
}
//序列化
private static void write() throws IOException {
//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Document\\Java\\myOtherStream\\oos.txt"));
//创建对象
Student s = new Student("张三", 22);
//void writerObject(Object obj):将指定的对象写入ObjectOutputStream
oos.writeObject(s);
//释放资源
oos.close();
}
}
4、Properties
Properties概述:
- 是一个Map体系的集合
- Properties可以保存到流中或从流中加载
package OtherStream_04;
import java.util.Properties;
import java.util.Set;
/*
Properties作为Map集合的使用
*/
public class PropertiesDemo {
public static void main(String[] args) {
// 创建Properties对象
// Properties<String ,String >prop=new Properties<String ,String>();
Properties prop = new Properties();
// 向Properties对象中添加键值对
prop.put("194001", "张三");
prop.put("194002", "李四");
prop.put("194003", "王五");
//遍历集合
Set<Object> keySet = prop.keySet();
for (Object key : keySet) {
Object value = prop.get(key);
System.out.println(key + "," + value);
}
}
}
Properties作为集合的特有方法:
方法名 | 说明 |
Object setProperty(String key,String value) | 设置集合的键和值,都是String类型,底层调用Hashtable方法put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set<String> stringPropertyNames() | 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
package OtherStream_04;
import java.util.Properties;
import java.util.Set;
/*
Properties作为集合的特有方法:
Object setProperty(String key,String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
String getProperty(String key):使用此属性列表中指定的键搜索属性
Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
*/
public class PropertiesDemo02 {
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//Object setProperty(String key,String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
prop.setProperty("194001", "张三");
/*
Object setProperty(String key, String value) {
return put(key, value);
}
Object put(Object key, Object value) {
return map.put(key, value);
}
*/
prop.setProperty("194002", "李四");
prop.setProperty("194003", "王五");
//String getProperty(String key):使用此属性列表中指定的键搜索属性
// System.out.println(prop.getProperty("194001"));
// System.out.println(prop.getProperty("1940004"));//null
//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);
}
}
}
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)方法的格式写入输出字符流 |
package OtherStream_04;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/*
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)方法的格式写入输出字符流
*/
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("D:\\Document\\Java\\myOtherStream\\fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("2022001", "张三");
prop.setProperty("2022002", "李四");
prop.setProperty("2022003", "王五");
//void store(Writer writer,String comments)
FileWriter fw = new FileWriter("D:\\Document\\Java\\myOtherStream\\fw.txt");
prop.store(fw, null);
fw.close();
}
}
package OtherStream_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/*
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)方法的格式写入输出字符流
*/
public class PropertiesDemo04 {
public static void main(String[] args) throws IOException {
//把几集合中的数据保存到文件
//myStore();
//把文件中的数据加载到集合
myLoad();
}
private static void myLoad() {
Properties prop = new Properties();
try {
//void load(InputStream inStream): 从输入字节流读取属性列表(键和元素对)
FileInputStream fis = new FileInputStream("D:\\Document\\Java\\myOtherStream\\fos.txt");
prop.load(fis);
fis.close();
System.out.println(prop);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("2022001", "张三");
prop.setProperty("2022002", "李四");
prop.setProperty("2022003", "王五");
//void store(OutputStream out,String comments): 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字节流
FileOutputStream fos = new FileOutputStream("D:\\Document\\Java\\myOtherStream\\fos.txt");
prop.store(fos, null);
fos.close();
}
}