缓冲流
缓冲流(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,因此需要进行适当的异常处理。