Java 中的字节流和字符流是输入和输出 IO 操作中的两种不同类型。虽然它们都可以读取和写入数据,但是它们在处理方式和运行方式上有明显的差异。下面我会详细讲解 Java 中的字节流和字符流的区别,以及它们各自的使用场景,同时给出两个实际场景的示例。
什么是字节流?
字节流是以字节为单位读取和写入数据的操作,数据是以二进制形式从源读入,并以二进制形式写入目标。字节流通常用于读取和写入图像、音频和视频文件等二进制文件,它们也被用于网络传输和套接字编程。
在 Java 中,字节流主要使用 InputStream
和 OutputStream
抽象类及其实现类来操作。例如,FileInputStream
和FileOutputStream
用于读写文件,Socket.getInputStream()
和 Socket.getOutputStream()
用于网络编程。
以下是一个字节流读取文件并输出到控制台的示例代码:
public static void readBytes(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
System.out.print(new String(buffer, 0, length));
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
什么是字符流?
字符流以字符为单位(或说以 Unicode 代码单元)读取和输出数据,是一种将字节编码转换为字符编码的操作。字符流通常用于处理文本文件,例如,读取和写入文本文件中的字符串。
在 Java 中,字符流主要使用 Reader
和 Writer
抽象类及其实现类来操作。例如,FileReader
和FileWriter
用于读写文件,BufferedReader
和 PrintWriter
用于网络编程。
以下是一个字符流读取文件并输出到控制台的示例代码:
public static void readChars(String fileName) {
try {
FileReader fr = new FileReader(fileName);
char[] buffer = new char[1024];
int length;
while ((length = fr.read(buffer)) > 0) {
System.out.print(new String(buffer, 0, length));
}
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
字节流和字符流的区别
在理解字节流和字符流的区别时,需要明确两个关键点:
- 字节流用于读写二进制数据,字符流用于读写字符数据;
- 字节流适用于图像、音频和视频文件等二进制文件,字符流适用于读写文本文件和网络编程中的字符串数据。
其它区别:
- 字节流是接口和抽象类的基础类,经常用于处理原始二进制数据。字符流是建立在字节流的基础之上的,字符流以字符的形式读写二进制数据,并将其转换为 Unicode 编码的字符。因为字符流带有字符集的信息,所以字符流更加高级。
- 字节流进行读写时用的是 byte[] 数组,字符流用的是 char[] 数组,字符流的缓冲区还可以自动转换字节与字符,与default charset有关,而字节流则是原始二进制数据。
- 字符流通常是建立在字节流之上的,所以它们维护着一个缓冲区(buffer),这使得操作大文件时要比使用原始的字节流(相当于没有缓冲区)更加高效。
- 字符流读写时会根据系统默认的字符集进行编码和解码,而字节流则没有默认的编码和解码方式。
- 字符流的操作比字节流的操作要慢,因为字符流在读取或写入时需要进行字符编码和解码,并且字符集的转换也需要时间、计算资源和内存。
示例说明
下面我们来看两个实际的示例,以更好地了解字节流和字符流的使用场景。
示例一
当我们需要读取的是一个文本文件时,我们通常会选择使用字符流进行读取。例如,我们要读取一个名字为 test.txt
的文件,文件中包含一些简单的文本。我们可以使用下面代码:
readChars("test.txt");
示例二
当我们需要读取的是二进制文件时,例如,我们需要读取一个 jpg 格式图片文件 test.jpg
。图片文件属于二进制文件,这时我们需要使用字节流。我们可以使用下面代码:
readBytes("test.jpg");
以上是对 Java 中的字节流和字符流进行了详细的讲解,关于 IO 操作的更多内容可以参考 Java 官方文档。当选择字节流和字符流时,需要根据实际需求的不同来选择适当的流类型,以达到最佳的读写效果。