按功能来分为输入流和输出流;按类型来分为字节流和字符流。
Java中的流都是从下面四个抽象基类中派生出来的:
- InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流;
- OutputStream/Writer:所有输出流的基类前者是字节输出流,后者是字符输出流。
一 、字节流
以字节为单位进行数据传输(8位),适用于处理二进制数据或者未经字符编码的文本数据。
InputStream字节输入流
InputStream
是 Java 中用于处理字节输入流的抽象类。它是所有字节输入流类的父类,提供了一些基本的方法来读取字节数据。
以下是 InputStream
类的一些主要方法和说明:
-
int read()
:- 从输入流中读取下一个字节的数据,并返回读取的字节(0~255之间的整数值),如果已经到达输入流的末尾,则返回 -1。
- 如果读取的字节为负数,则表示字节数据的最高位为 1,需要转换为无符号整数才能正确表示字节的值。
-
int read(byte[] b)
:- 从输入流中读取多个字节的数据,并将其存储到字节数组
b
中。 - 返回实际读取的字节数,如果已经到达输入流的末尾,则返回 -1。
- 从输入流中读取多个字节的数据,并将其存储到字节数组
-
int read(byte[] b, int off, int len)
:- 从输入流中读取多个字节的数据,并将其存储到字节数组
b
中,从偏移量off
开始存储,最多读取len
个字节。 - 返回实际读取的字节数,如果已经到达输入流的末尾,则返回 -1。
- 从输入流中读取多个字节的数据,并将其存储到字节数组
-
long skip(long n)
:- 跳过输入流中的
n
个字节,返回实际跳过的字节数。 - 注意:该方法不保证一定成功跳过
n
个字节,可能会跳过比n
少的字节数。
- 跳过输入流中的
-
int available()
:- 返回可以从输入流中读取而不受阻塞的字节数。
- 注意:
available()
方法返回的字节数可能不准确,不应该用于检查是否已经读取完所有的数据。
-
void close()
:- 关闭输入流并释放与之相关的资源。
以下是一个简单的示例代码,演示如何使用
InputStream
来读取文件中的字节数据:import java.io.*; public class InputStreamExample { public static void main(String[] args) { try { // 创建一个 FileInputStream 对象来读取文件 InputStream inputStream = new FileInputStream("example.txt"); // 读取文件中的字节数据 int data; while ((data = inputStream.read()) != -1) { // 将读取的字节数据转换为字符并打印出来 System.out.print((char) data); } // 关闭输入流 inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
在这个示例中,我们使用
FileInputStream
来创建一个InputStream
对象,然后通过read()
方法逐个字节地读取文件中的数据,直到到达文件末尾(read()
方法返回 -1)。每次读取到一个字节后,我们将其转换为字符并打印出来。需要注意的是,在实际开发中,应该始终在使用完毕后关闭输入流,以释放相关资源。因此,我们在
finally
块中调用close()
方法来关闭输入流,以确保即使发生异常,输入流也能够被正确关闭。
InputStream
是一个抽象类,不能直接实例化,常用的实现类包括:
FileInputStream
:用于从文件中读取数据。ByteArrayInputStream
:用于从内存中的字节数组读取数据。BufferedInputStream
:提供了缓冲功能,提高了读取效率。DataInputStream
:用于从输入流中按照基本数据类型进行数据读取。
import java.io.*; public class InputStream示例 { public static void main(String[] args) { try { // FileInputStream: 从文件读取数据 FileInputStream fileInputStream = new FileInputStream("example.txt"); int byteRead; System.out.println("使用FileInputStream从文件中读取数据:"); while ((byteRead = fileInputStream.read()) != -1) { System.out.print((char) byteRead); } fileInputStream.close(); // ByteArrayInputSteam: 从字节数组读取数据 byte[] byteArray = { 65, 66, 67, 68, 69 }; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray); System.out.println("\n\n使用ByteArrayInputStream从字节数组中读取数据:"); int byteReadFromByteArray; while ((byteReadFromByteArray = byteArrayInputStream.read()) != -1) { System.out.print((char) byteReadFromByteArray); } byteArrayInputStream.close(); // BufferedInputStream: 带缓冲地从文件读取数据 FileInputStream fileInputStream2 = new FileInputStream("example.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream2); System.out.println("\n\n使用BufferedInputStream从文件中读取数据:"); int byteReadBuffered;