前言
在java中,流是一个非常重要的概念。它是java IO中一个基本的数据传输单元。流可以分为字节流和字符流。字节流和字符流都可以进行输入和输出操作。不同的是,字节流可以操作所有类型的二进制数据,而字符流只能操作文本数据。在本篇文章中,我将详细介绍java中的字节流和字符流。
Java程序中的IO和文件处理通常使用流来实现。流是一种逐个操作的数据序列。输入操作从流中读入数据并放入程序,输出操作将数据从程序中发送到流中。Java IO提供了两种类型的流:字节流和字符流。字节流和字符流之间最大的区别是字节流每次操作的都是8位二进制数据,而字符流每次操作的是16位Unicode字符。
一、字节流
Java中提供了两个基本的抽象字节流类:InputStream和OutputStream。InputStream 是所有输入流的父类,而OutputStream 是所有输出流的父类。InputStream 类和 OutputStream 类完成了字节流的读写操作,各种输入/输出数据类型 (如 int、char、short )都可以通过字节流进行读写。InputStream 和 OutputStream 类实现了Java中文件/网络操作的核心。其中FileOutputStream可以向本地文件系统中写入字节数据,ByteArrayOutputStream可以写入数据到内存中的byte数组中,FilterOutputStream可以对其他字节流进行包装,添加一些装饰功能。字节流可以操作所有类型的二进制数据,包括图像、音频、视频等,非常适合于对于二进制文件的读写操作。
以下是一个使用字节流读取文件并进行复制的示例代码:
public static void copyFile(String sourceFileName, String targetFileName) throws IOException {
// 创建文件输入流和文件输出流
FileInputStream in = new FileInputStream(sourceFileName);
FileOutputStream out = new FileOutputStream(targetFileName);
// 实现读写操作
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
// 关闭输入输出流
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
在上面代码中,我们先使用FileInputStream类创建一个输入流对象,使用FileOutputStream类创建一个输出流对象,并创建一个4KB大小的缓冲区,然后每次从输入流中读取缓冲区大小的数据,再将其写入输出流中,循环进行直到读取完整个文件,最后将输入输出流关闭即可。
以下是一个读取文件并输出到控制台的示例:
InputStream input = null;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while(data != -1) {
System.out.print((char) data);
data = input.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、字符流
在Java中,字符流主要有Reader和Writer两类,用于操作文本数据,提供了一些常用的方法来处理字符流。字符流支持Unicode字符集,并且会自动处理不同操作系统中的文本换行符。与字节流相似,字符流也有许多操作类,如FileReader、BufferedReader、StringReader等。
以下是一个使用字符流读取文件并进行复制的示例代码:
public static void copyFile(String sourceFileName, String targetFileName) throws IOException {
// 创建文件读取器和文件写入器
FileReader in = new FileReader(sourceFileName);
FileWriter out = new FileWriter(targetFileName);
// 实现读写操作
char[] buffer = new char[4096];
int charsRead;
while ((charsRead = in.read(buffer)) != -1) {
out.write(buffer, 0, charsRead);
}
// 关闭读取器和写入器
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
在上面代码中,我们先使用FileReader类创建一个读取器对象,使用FileWriter类创建一个写入器对象,并创建一个4KB大小的缓冲区,然后每次从读取器中读取缓冲区大小的数据,再将其写入写入器中,循环进行直到读取完整个文件,最后将读取器和写入器关闭即可。
以下是一个从文件中读取字符并输出到控制台的示例:
Reader reader = null;
try {
reader = new FileReader("file.txt");
int data = reader.read();
while(data != -1) {
System.out.print((char) data);
data = reader.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
Java提供了字节流和字符流来进行数据输入/输出操作。字节流可以读写所有类型的二进制数据(如图像、音频、视频等),而字符流只能操作文本数据。字节流和字符流都是以 InputStream 或者 Reader 类为基础来向上封装出来的。对于简单的数据读取和写入操作,使用比较简单的 InputStream 或者 Reader 类是比较方便的。在实际开发中,我们应该根据具体的使用需求来选择适合的IO方式,以达到最佳的IO性能和应用效果。