InputStream
是 Java 中用于从输入源读取数据的抽象类。它是所有输入流类的基类,提供了一系列方法来读取不同类型的数据。
要使用InputStream
,你需要以下步骤:
- 创建
InputStream
对象:可以使用具体的InputStream
子类,如FileInputStream
、ByteArrayInputStream
等,根据你的需求选择适当的子类。 - 打开输入流:通过创建的
InputStream
对象,打开与输入源(文件、网络连接等)之间的连接。 - 读取数据:使用
InputStream
对象的read()
方法或其变种方法,从输入源中读取数据。read()
方法返回一个整数值,表示读取到的字节数据。如果已经到达输入流的末尾,则返回-1
。 - 处理读取的数据:对读取到的数据进行处理,可以将其写入文件、内存缓冲区等,或者直接在程序中使用。
- 关闭输入流:在处理完数据后,使用
close()
方法关闭输入流,释放资源。
下面是一个简单的示例代码,演示如何使用InputStream
读取文件内容:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamExample {
public static void main(String[] args) {
try {
// 创建InputStream对象
InputStream inputStream = new FileInputStream("path/to/file.txt");
// 读取数据
int data;
while ((data = inputStream.read()) != -1) {
// 处理读取的数据,这里只简单地输出到控制台
System.out.print((char) data);
}
// 关闭输入流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在这个示例中,我们首先创建了一个FileInputStream
对象来读取文件内容。然后使用while
循环和read()
方法逐字节地读取数据,并将其转换为字符类型进行输出。最后,在处理完数据后,调用close()
方法关闭输入流。 请注意,这只是InputStream
的基本用法示例,实际应用中可能会有更复杂的操作和异常处理。你可以根据具体需求选择合适的InputStream
子类,并参考 Java 文档以获取更详细的信息。
InputStream 缓冲
InputStream 缓冲是一种在读取数据时提高性能的技术。当你使用原始的InputStream
对象读取数据时,它会逐个字节地从输入源中读取数据,并且每次读取都需要与输入源进行交互,这可能会导致较慢的读取速度。
为了解决这个问题,Java提供了一个称为BufferedInputStream
的类,它是InputStream
的装饰器(Decorator)。BufferedInputStream
内部维护了一个内存缓冲区,可以一次性读取多个字节到缓冲区中,然后根据需要从缓冲区中返回数据,而不必每次都与输入源进行交互。
使用InputStream
缓冲的好处是可以减少对底层输入流的频繁访问,从而提高读取数据的效率。特别是当你需要连续读取大量数据时,使用缓冲可以显著降低I/
O操作的开销。
要使用InputStream
缓冲,你可以按照以下步骤进行操作:
- 创建一个
InputStream
对象,例如FileInputStream
或者其他类型的输入流。 - 将该
InputStream
对象传递给BufferedInputStream
的构造函数,创建一个BufferedInputStream
对象。 - 使用
BufferedInputStream
对象读取数据,可以使用read()
方法读取单个字节,或者使用read(byte[] buffer)
方法读取一定数量的字节并存储到指定的缓冲区中。 - 处理读取到的数据。
- 关闭
BufferedInputStream
对象,这将同时关闭底层的InputStream
对象。
下面是一个简单的示例代码,演示如何使用BufferedInputStream
来读取文件内容:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInputStreamExample {
public static void main(String[] args) {
try (FileInputStream fileInputStream = new FileInputStream("example.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
// 处理读取到的数据,例如打印或写入其他地方
System.out.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们首先创建了一个FileInputStream
对象,并将其传递给BufferedInputStream
的构造函数。然后,我们使用while
循环从缓冲区中连续读取数据,并处理每次读取到的字节数据。 请注意,在使用完毕后,我们使用try-with-resources
语句关闭了BufferedInputStream
和FileInputStream
对象,以确保资源被正确释放。
InputStream 阻塞
InputStream
在读取数据时可能会发生阻塞。当你调用InputStream
的read()
方法来读取数据时,如果没有可用的数据可供读取,该方法将会阻塞直到有新的数据可用或者达到了流的末尾。
这种阻塞行为可以确保程序在读取数据时不会消耗过多的资源,因为它只会在有数据可用时才会继续执行。但是,如果你需要更高的读取性能,特别是在处理大量数据时,阻塞可能会成为一个问题。
为了提高读取性能,你可以使用BufferedInputStream
类来包装原始的InputStream
对象。BufferedInputStream
实际上是对输入流进行了缓冲,它会一次性从底层输入流中读取一块数据,并将其存储在内部缓冲区中。然后,每次调用read()
方法时,它会从缓冲区中返回数据,而不是直接从底层输入流中读取数据。
通过使用BufferedInputStream
,你可以减少与底层输入流的交互次数,从而提高读取性能。此外,BufferedInputStream
还提供了mark()
和reset()
等方法,允许你在缓冲区中设置标记并跳回到该位置,以便重新读取数据。
下面是使用BufferedInputStream
的基本步骤:
- 创建一个
InputStream
对象,例如FileInputStream
或者Socket.getInputStream()
。 - 使用该
InputStream
对象创建一个BufferedInputStream
对象,例如:BufferedInputStream bufferedInput = new BufferedInputStream(inputStream)
。 - 使用
bufferedInput
对象的read()
方法读取数据。
这是一个使用BufferedInputStream
读取文件的示例代码:
try {
InputStream inputStream = new FileInputStream("file.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(inputStream);
int data;
while ((data = bufferedInput.read()) != -1) {
// 处理读取到的数据
System.out.print((char) data);
}
bufferedInput.close();
} catch (IOException e) {
e.printStackTrace();
}
在上面的示例中,我们首先创建了一个FileInputStream
对象来读取名为file.txt
的文件。然后,我们将它包装在一个BufferedInputStream
对象中,并使用read()
方法逐个字节地读取数据并处理它们。
InputStream 实现类
InputStream
是 Java IO 库中用于读取字节流的抽象类。它是一个基类,具体的实现类包括:
FileInputStream
:从文件中读取数据。ByteArrayInputStream
:从内存中的字节数组读取数据。PipedInputStream
:从管道中读取数据。FilterInputStream
的子类,如BufferedInputStream
、DataInputStream
等。 这些实现类提供了不同的方式来获取输入流,并且可以根据需要进行适当的配置和处理。