1.特殊操作流
1.1标准输入输出流
System类中有两个静态成员变量:
- public static final InputStream in:“标准”输入流。 提供输入数据。 通常,该流对应于键盘输入或由主机环境或用户指定的另一个输入源。
- public static final PrintStream out:“标准”输出流。 接受输出数据。 通常,此流对应于显示输出或由主机环境或用户指定的另一个输出目标。
标准输入流
自己实现键盘录入数据:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Java提供Scanner类实现键盘录入
Scanner sc = new Scanner(System.in);
输出语句的本质:是一个标准输出流:
PrintStream ps = Syetem.out
PrintStream 类有的方法,Syetem.out都可以使用
代码示例:
package Java26;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
public class demo {
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(InputStream in)
// 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);
}
}
package Java26;
import java.io.BufferedWriter;
import java.io.PrintStream;
public class demo1 {
public static void main(String[] args) {
//public static final PrintStream out:“标准”输出流。
PrintStream ps = System.out;
ps.println("hello");
ps.println(100);
//System.out本质是一个字节输出流
System.out.println("hello");
System.out.println(100);
}
}
1.2 打印流
打印流分为:
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
字符打印流的基本使用:
package Java26;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class demo2 {
public static void main(String[] args) throws IOException {
//PrintWriter(String fileName)
//使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新。
// PrintWriter pw = new PrintWriter("D:\\lyy\\pw.txt");
// pw.write("hello");
// pw.write("\r\n");
// pw.flush();
// pw.write("world");
// pw.write("\r\n");
// pw.flush();
// //println()方法会自动换行,相当于两步writer()方法
// pw.println("hello");
// pw.flush();
// pw.println("world");
// pw.flush();
//public PrintWriter(Writer out,boolean autoFlush)创建一个新的PrintWriter。
//参数
//out - 字符输出流
//autoFlush - 一个布尔值 如果为真,则println,printf,或format方法将刷新输出缓冲区
PrintWriter pw = new PrintWriter(new FileWriter("D:\\lyy\\pw.txt"),true);
pw.println("hello");
pw.println("world");
pw.close();
}
}
字符打印流复制文件
package Java26;
import java.io.*;
public class demo3 {
public static void main(String[] args) throws IOException {
/* //根据数据源创建字符输入流对象
BufferedReader br = new BufferedReader(new FileReader("D:\\lyy\\src\\Java25\\demo.java"));
//根据目的地创建字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\lyy\\copy.java"));
//读写数据,复制文件
String line;
while ((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();*/
//用打印流改进
BufferedReader br = new BufferedReader(new FileReader("D:\\lyy\\src\\Java25\\demo.java"));
PrintWriter pw = new PrintWriter(new FileWriter("D:\\lyy\\copy.java"),true);
//读写数据复制文件
String line;
while ((line=br.readLine())!=null){
pw.println(line);
}
pw.close();
br.close();
}
}
1.3 对象序列化流
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后相当于文件中持久保存了一个对象的信息。
要实现对象序列化和反序列化就要使用对象序列化流和对象反序列化流:
- 对象序列化流:ObjectOutputStream
- 对象反序列化流:ObjecIntputStream
对象序列化流:ObjectOutputStream
ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。
构造方法:
ObjectOutputStream(OutputStream out)
创建一个写入指定的OutputStream的ObjectOutputStream。
序列化对象的方法:
writeObject(Object obj)
将指定的对象写入ObjectOutputStream
注意:
- 一个对象要想被序列化,该对象所属的类必须实现Serializable接口
- Serializable是一个标配接口,实现该接口不需要重写任何方法
package Java26;
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 Java26;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
//NotSerializableException:抛出一个实例需要一个Serializable接口。 序列化运行时或实例的类可能会抛出此异常。
//类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。
public class demo4 {
public static void main(String[] args) throws IOException {
//ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\lyy\\oos.txt"));
//创建对象
Student s = new Student("lyy",24);
//void writeObject(Object obj)
//将指定的对象写入ObjectOutputStream
oos.writeObject(s);
oos.close();
}
}
对象反序列化流:ObjecIntputStream
ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。
构造方法:
ObjectInputStream(InputStream in)
创建从指定的InputStream读取的ObjectInputStream。
反序列化对象的方法:
readObject()
从ObjectInputStream读取一个对象。
package Java26;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class demo5 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//ObjectInputStream(InputStream in)
//创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\lyy\\oos.txt"));
//readObject()
//从ObjectInputStream读取一个对象。
Object obj = ois.readObject();
//学生类型,向下转型
Student s = (Student) obj;
System.out.println(s.getName()+","+s.getAge());
ois.close();
}
}
- 对象序列化流序列化一个对象后,如果修改对象所属文件类型,读取数据会不会出问题?
- 会
- 如果出问题,该如何解决?
*通过给对象所属的添加序列化ID值 - 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?
- 对象中的成员变量用transient修饰,则该成员变量不参与序列化
package Java26.Demo;
import java.io.Serializable;
public class Student implements Serializable {
//声明序列化ID值
private static final long serialVersionUID = 42L;
private String name;
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 Java26.Demo;
import java.io.*;
/*
* 对象序列化流序列化一个对象后,如果修改对象所属文件类型,读取数据会不会出问题?
* 会
* 如果出问题,该如何解决?
*通过给对象所属的添加序列化ID值
* 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?
* 对象中的成员变量用transient修饰,则该成员变量不参与序列化
* */
public class demo {
public static void main(String[] args) throws IOException, ClassNotFoundException{
// write();
read();
}
//反序列化
private static void read() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\lyy\\oos.txt"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName()+","+s.getAge());
ois.close();
}
//序列化
private static void write() throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\lyy\\oos.txt"));
Student s = new Student("lyy",24);
oos.writeObject(s);
oos.close();
}
}
1.3 Properties
Properties概述
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
Properties作为集合的使用
package Java26.Demo2;
import java.util.Properties;
import java.util.Set;
public class demo {
public static void main(String[] args) {
//创建集合对象
// Properties<String,String> prop = new Properties<String,String>();错误写法
Properties prop = new Properties();
//存储元素
prop.put("001","lyy");
prop.put("002","lyq");
prop.put("003","lys");
//遍历集合
Set<Object> keySet = prop.keySet();
for (Object key : keySet){
Object value=prop.get(key);
System.out.println(key+","+value);
}
}
}
Properties作为集合的特有方法
package Java26.Demo2;
import java.util.Properties;
import java.util.Set;
public class demo2 {
public static void main(String[] args) {
Properties prop = new Properties();
//public Object setProperty(String key,String value)
// 设置集合的键和值,都是String类,底层调用Hashtable方法put
prop.setProperty("001","lyy");
prop.setProperty("002","dwa");
prop.setProperty("003","fqe");
//public String getProperty(String key, String defaultValue)
// 使用此属性列表中指定的键搜索属性。
System.out.println(prop.getProperty("001"));
System.out.println(prop);
Set<String> names = prop.stringPropertyNames();
for(String k:names){
String value = prop.getProperty(k);
System.out.println(k+value);
}
}
}
Properties和IO流结合的方法
package Java26.Demo3;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class demo {
public static void main(String[] args) throws IOException{
//把集合中的数据保存到文件
// myStore();
//把文件中的数据保存到集合
myLoad();
}
private static void myLoad() throws IOException{
Properties prop = new Properties();
//public void load(Reader reader)
//以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。
FileReader fr = new FileReader("D:\\lyy\\fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
private static void myStore()throws IOException {
Properties prop = new Properties();
prop.setProperty("001","lyy");
prop.setProperty("002","fea");
prop.setProperty("003","few");
//public void store(Writer writer,String comments)
//将此Properties表中的此属性列表(键和元素对)以适合使用load(Reader)方法的格式写入输出字符流
FileWriter fw = new FileWriter("D:\\lyy\\fw.txt");
prop.store(fw,null);
fw.close();
}
}