缓冲流
缓冲流(Buffered Stream)也被称为高效流,它是对基本的字节字符流进行增强的一种流。通过缓冲流,可以提高数据的读写能力。
在创建缓冲流对象时,会创建一个内置的默认大小的缓冲区数组。通过对缓冲区的读写,可以减少系统的IO次数,从而提高读写的效率。
Java中提供了多种缓冲流类,包括BufferedReader、BufferedWriter、BufferedInputStream和BufferedOutputStream。这些类分别对应于不同类型的I/O操作:
- BufferedReader 和 BufferedWriter 是字符缓冲流,分别用于字符输入和输出。
- BufferedInputStream 和 BufferedOutputStream 是字节缓冲流,分别用于字节输入和输出。
字节缓冲流
实例
通过字节缓存流来提高读写效率
import java.io.*;
public class IOLearn3 {
public static void main(String[] args) throws Exception {
//创建一个FileInputStream对象
InputStream fileInputStream = new FileInputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//缓冲输入流包装原始的字节输入流
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
//创建文件输出流对象
OutputStream fileOutputStream = new FileOutputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\b.txt");
//缓冲输出流包装原始的字节输出流
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
//读取a.txt文件中的数据写入到b.txt中
int data;
while ((data=bufferedInputStream.read())!=-1){
bufferedOutputStream.write(data);
}
//关闭流
bufferedOutputStream.close();
bufferedInputStream.close();
fileOutputStream.close();
fileInputStream.close();
}
}
字符缓冲流
实例
通过字符缓冲流提高读写效率
import java.io.*;
public class IOLearn6 {
public static void main(String[] args) throws Exception {
//创建字符输入管道
FileReader fileReader=new FileReader("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//字符缓冲流包装原始字符流
BufferedReader bufferedReader=new BufferedReader(fileReader);
//创建字符输出管道
FileWriter fileWriter=new FileWriter("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\b.txt");
//字符缓冲输出流包装原始字符输出流、
BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);
int data;
while((data=bufferedReader.read())!=-1){
bufferedWriter.write(data);
}
//关闭流
bufferedWriter.close();
bufferedReader.close();
fileWriter.close();
fileReader.close();
}
}
关闭流的两种方式
改写字符缓冲流的实例
1.try-catch-finally
import java.io.*;
public class IOLearn6 {
public static void main(String[] args) throws IOException {
FileReader fileReader=null;
BufferedReader bufferedReader=null;
FileWriter fileWriter=null;
BufferedWriter bufferedWriter=null;
try{
//创建字符输入管道
fileReader=new FileReader("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//字符缓冲流包装原始字符流
bufferedReader=new BufferedReader(fileReader);
//创建字符输出管道
fileWriter=new FileWriter("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\b.txt");
//字符缓冲输出流包装原始字符输出流、
bufferedWriter=new BufferedWriter(fileWriter);
int data;
while((data=bufferedReader.read())!=-1){
bufferedWriter.write(data);
}
}catch (IOException e){
e.printStackTrace();
}finally {
//关闭流
bufferedWriter.close();
bufferedReader.close();
fileWriter.close();
fileReader.close();
}
}
}
2.try-with-resource
import java.io.*;
public class IOLearn6 {
public static void main(String[] args) throws Exception {
try( //创建一个FileInputStream对象
InputStream fileInputStream = new FileInputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//缓冲输入流包装原始的字节输入流
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
//创建文件输出流对象
OutputStream fileOutputStream = new FileOutputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\b.txt");
//缓冲输出流包装原始的字节输出流
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(fileOutputStream);){
//读取a.txt文件中的数据写入到b.txt中
int data;
while ((data=bufferedInputStream.read())!=-1){
bufferedOutputStream.write(data);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
字符转换流(解决不同编码情况下,读取字符乱码问题)
解决步骤:获取原始字节输入流,通过指定的字符集转换成字符输入流
字符转换流(Character Conversion Streams)在Java的I/O库中指的是那些能够在字节流和字符流之间进行转换的流。字符流(如Reader和Writer)处理的是char类型的数据,而字节流(如InputStream和OutputStream)处理的是byte类型的数据。当你要在字节流和字符流之间进行转换时,就需要使用字符转换流。
Java提供了几个类来实现这种转换,其中最常用的是InputStreamReader和OutputStreamWriter。这些类允许你把字节流转换为字符流,或者把字符流转换为字节流。
实例一
将a.txt以GBK字符集读取
import java.io.*;
public class IOLearn7 {
public static void main(String[] args) throws Exception {
try( //创建一个FileInputStream对象
InputStream fileInputStream = new FileInputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//将字节输入流转换成指定字符集的字符输入流
InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream,"GBK");
){
//读取a.txt文件中的数据
int data;
while ((data=inputStreamReader.read())!=-1){
System.out.print((char)data);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
结果:
实例二
将a.txt(GBK编码)中的数据写入到b.txt(UTF-8编码)
import java.io.*;
public class IOLearn7 {
public static void main(String[] args) throws Exception {
try( //创建一个FileInputStream对象
InputStream fileInputStream = new FileInputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\a.txt");
//将字节输入流转换成指定字符集的字符输入流
InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream,"GBK");
//创建字节输出流
OutputStream outputStream=new FileOutputStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\b.txt");
//将字节输出流转换成指定字符集的字符输出流
OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream, "UTF-8");
){
//读取a.txt文件中的数据
int data;
while ((data=inputStreamReader.read())!=-1){
//它会将字符编码为字节,并将这些字节存储在缓冲区中。
outputStreamWriter.write(data);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
打印流
打印流(Print Stream)**在Java中,特指PrintStream和PrintWriter这两个类,它们主要用于方便地打印各种数据值的表现形式到指定的输出目标,如控制台、文件等。
- PrintStream:这是字节打印流,继承自OutputStream,主要用于写字节数据。它提供了print和println方法,可以打印数据并自动进行换行。创建PrintStream对象时,可以指定目标输出,例如文件或OutputStream。
- PrintWriter:这是字符打印流,继承自Writer,主要用于写字符数据。与PrintStream类似,它也提供了print和println方法。当启用自动刷新时,调用println、printf或format方法会立即刷新输出
实例一
import java.io.IOException;
import java.io.PrintStream;
public class IOlearn8 {
public static void main(String[] args) {
try (PrintStream printStream = new PrintStream("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\src\\print.txt");
){
System.setOut(printStream);//指定打印流对象
System.out.println("test printStream");//打印到文件中
}catch (IOException e){
e.printStackTrace();
}
}
}
结果
实例二
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
public class IOlearn8 {
public static void main(String[] args) {
try (PrintWriter printWriter = new PrintWriter("C:\\Users\\bumiexiguang\\OneDrive\\桌面\\lambada\\src\\print.txt");
){
printWriter.println("test1");
printWriter.println("test2");
printWriter.println("test3");
}catch (IOException e){
e.printStackTrace();
}
}
}
序列化流
序列化流在Java中指的是将对象的状态转换为可以存储或传输的形式的过程,以及随后将这个形式的数据恢复为对象的过程。这个过程涉及到两个核心的概念:序列化和反序列化。
**序列化(Serialization)**是将对象的状态转换为字节流的过程,这样可以将对象的状态保存到磁盘、数据库或通过网络发送到另一台机器。序列化流就是用于执行这个转换过程的输出流。
**反序列化(Deserialization)**则是将之前序列化保存的字节流恢复为对象的过程。反序列化流是用于执行这个恢复过程的输入流。
在Java中,要实现对象的序列化,需要让类实现Serializable接口。这个接口是一个标记接口,没有任何方法需要实现,它仅仅是一个标识符,告诉Java运行时系统这个类的对象可以被序列化。
Java提供了ObjectOutputStream类来执行序列化操作,它可以将对象序列化到输出流中。同时,ObjectInputStream类用于执行反序列化操作,它可以从输入流中读取序列化数据并创建对象。
下面是一个简单的例子,展示了如何使用ObjectOutputStream和ObjectInputStream进行序列化和反序列化:
import java.io.*;
// 假设有一个类Person实现了Serializable接口
class Person implements Serializable {
private String name;
private int age;
// 构造方法、getter和setter方法
// ...
}
public class SerializationExample {
public static void main(String[] args) {
try {
// 序列化对象到文件
Person person = new Person("Alice", 30);
FileOutputStream fos = new FileOutputStream("person.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(person);
oos.close();
// 从文件中反序列化对象
FileInputStream fis = new FileInputStream("person.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Person deserializedPerson = (Person) ois.readObject();
ois.close();
// 输出反序列化后的对象信息
System.out.println("Deserialized Person:");
System.out.println("Name: " + deserializedPerson.getName());
System.out.println("Age: " + deserializedPerson.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
在这个例子中,Person类实现了Serializable接口,因此可以被序列化。ObjectOutputStream用于将Person对象序列化到文件person.ser中,而ObjectInputStream则用于从该文件中反序列化对象。注意,序列化时可能会 抛出IOException,反序列化时可能会抛出IOException和ClassNotFoundException,因此需要进行适当的异常处理。