转换流
InputStreamReader/OutputStreamWriter用来实现将字节流转化成字符流。
通过转换流解决乱码
import java.io.FileInputStream;
import java.io.InputStreamReader;
//转换流
public class TestInputStreamReader {
//通过转换流解决乱码问题
public static void main(String[] args) {
//创建文件输入流对象
try(FileInputStream fileInputStream = new FileInputStream("src/main/java/IOStream/a.txt");
//创建字节到字符的转换流
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"gbk")){
//创建转换流(字节到字符的转换)流对象,并在该对象中指定编码。
int temp = 0;
StringBuilder stringBuilder = new StringBuilder();
while ((temp = inputStreamReader.read())!=-1){
stringBuilder.append((char) temp);
}
System.out.println(stringBuilder);
}catch (Exception e){
e.printStackTrace();
}
}
}
通过转换流实现键盘输入屏幕输出
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Objects;
public class TestConvertStream {
public static void main(String[] args) {
//创建键盘输入相关流对象
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//创建向屏幕输入相关流对象
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out))){
while (true){
bufferedWriter.write("请输入:");
bufferedWriter.flush();
String s = bufferedReader.readLine();
if (Objects.equals(s,"exit")){
bufferedWriter.write("拜拜!!");
break;
}
bufferedWriter.write("您输入的是:"+s);
bufferedWriter.newLine();
bufferedWriter.flush();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
通过字符输出流添加行号
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class TestLineNumber3 {
public static void main(String[] args) {
try(PrintWriter pw = new PrintWriter("src/main/java/IO流补充/b.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("src/main/java/IO流补充/a.txt")))){
String s = "";
int temp = 1;
while ((s = bufferedReader.readLine())!=null){
pw.println(temp+"."+s);
temp++;
}
pw.flush();
}catch (Exception e){
e.printStackTrace();
}
}
}
数据流(不常用,了解即可)
数据流将“基本数据类型与字符串类型”作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。DataInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类型数据(如:int、double、String等)的方法。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class TestDataStream {
public static void main(String[] args) {
try(DataInputStream dataInputStream = new DataInputStream(new FileInputStream("src/main/java/IOstream/a.txt"));
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("src/main/java/IOstream/a.txt"))){
dataOutputStream.writeBoolean(true);
dataOutputStream.writeByte(1);
dataOutputStream.writeChar('c');
dataOutputStream.writeDouble(5.21);
dataOutputStream.writeInt(521);
dataOutputStream.writeUTF("刘浩琦");
//手动刷新缓冲区:将流中数据写入到文件中
dataOutputStream.flush();
//直接读取数据:读取的顺序要与写入的顺序一致,否则不能正确读取数据。
System.out.println(dataInputStream.readBoolean());
System.out.println(dataInputStream.readByte());
System.out.println(dataInputStream.readChar());
System.out.println(dataInputStream.readDouble());
System.out.println(dataInputStream.readInt());
System.out.println(dataInputStream.readUTF());
}catch (Exception e){
e.printStackTrace();
}
}
}
使用数据流时,读取的顺序一定要与写入的顺序一致,否则不能正确读取数据。
对象流
我们前边学到的数据流只能实现对基本数据类型和字符串类型的读写,并不能读取对象(字符串除外),如果要对某个对象进行读写操作,我们需要学习一对新的ObjectInputStream/ObjectOutputStream
处理基本数据类型数据
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//处理基本数据类型数据
public class TestObjectStreamBasicType {
public static void main(String[] args) {
try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("src/main/java/IOStream/b.txt",false));
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src/main/java/IOStream/b.txt"))){
//将如下数据写入到文件中
objectOutputStream.writeInt(20);
objectOutputStream.writeDouble('c');
objectOutputStream.flush();
//必须要按照写入的顺序读取数据
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readDouble());
}catch (Exception e){
e.printStackTrace();
}
}
}
Java对象的序列化和反序列化(重点)
序列化涉及的类和接口
ObjectOutputStream代表对象输出流,它的writeObject(Objectobj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其
返回。只有实现了Serializable接口的类的对象才能被序列化。Serializable接口是一个空接口,只起到标记作用。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//序列化与反序列化对象
public class TestObjectOutputStream {
public static void main(String[] args) {
try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("src/main/java/IOStream/b.txt"));
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src/main/java/IOStream/b.txt"))){
User user = new User("刘浩琦",19);
objectOutputStream.writeObject(user);
objectOutputStream.flush();
User user1 = (User)objectInputStream.readObject();
System.out.println(user1);
}catch (Exception e){
e.printStackTrace();
}
}
}
import java.io.Serializable;
public class User implements Serializable {
private String name;
private int age;
public User() {
}
public User(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 "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}