Java InputStream
最后修改日期:2024年2月21日
在本文中,我们将展示如何在 Java 中使用 InputStream 类。
Java 流是从源到目标的数据流。 Java 流的一个很好的比喻是水从水龙头流入浴缸,然后流入排水管。 InputStream 和 OutputStream 是对底层数据访问的抽象,例如 C 文件指针。
InputStream 是用于读取数据的源。流可以表示各种类型的源,包括磁盘文件、设备、其他程序和内存数组。
流支持许多不同的数据类型,包括简单字节、原始数据类型、本地化字符和对象。
子类
InputStream 是一个抽象类;它是表示字节输入流的所有类的超类,包括 AudioInputStream、ByteArrayInputStream、FileInputStream、FilterInputStream、ObjectInputStream、PipedInputStream 和 SequenceInputStream。
close 方法
FileInputStream 的 close 方法关闭输入流并释放与此流关联的任何系统资源。在我们的示例中,我们使用try-with-resources语句,以确保每个资源在语句结束时都会关闭。
read 方法
InputStream 使用以下 read 方法读取字节
read(byte[] b)— 从此输入流中最多读取b.length个字节的数据到字节数组中。read(byte[] b, int off, int len)— 从此输入流中最多读取len个字节的数据到字节数组中。read— 从文件输入流中读取一个字节。
读取文本
以下示例展示了如何使用 InputStream 读取文本文件。
The Battle of Thermopylae was fought between an alliance of Greek city-states, led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the course of three days, during the second Persian invasion of Greece.
在此示例中,我们使用此文本文件。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
void main() throws IOException {
String fileName = "thermopylae.txt";
try (InputStream fis = new FileInputStream(fileName);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
br.lines().forEach(line -> System.out.println(line));
}
}
文本文件通过 FileInputStream、InputStreamReader 和 BufferedReader 读取。
try (InputStream fis = new FileInputStream(fileName);
FileInputStream 是 InputStream 的一个特化,用于从文件读取字节。
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
InputStreamReader 是从字节流到字符流的桥梁:它读取字节并使用指定的字符集将其解码为字符。
BufferedReader br = new BufferedReader(isr)) {
BufferedReader 从字符输入流中读取文本,缓冲字符以高效地读取字符、数组和行。
br.lines().forEach(line -> System.out.println(line));
数据通过缓冲读取器按行读取。
读取字节
InputStream 的 read 方法读取字节。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
void main() throws IOException {
String fileName = "ball.png";
try (InputStream is = new FileInputStream(fileName)) {
byte[] buffer = new byte[is.available()];
is.read(buffer);
int i = 0;
for (byte b : buffer) {
if (i % 10 == 0) {
System.out.println();
}
System.out.printf("%02x ", b);
i++;
}
}
System.out.println();
}
该示例从 PNG 图像读取字节,并将字节以十六进制格式打印到控制台。
try (InputStream is = new FileInputStream(fileName)) {
我们使用 FileInputStream 从图像文件读取字节。
byte[] buffer = new byte[is.available()]; is.read(buffer);
使用 read 方法,我们将字节读取到字节数组中。
int i = 0;
for (byte b: buffer) {
if (i % 10 == 0) {
System.out.println();
}
System.out.printf("%02x ", b);
i++;
}
我们遍历数组并将字节以十六进制格式打印到控制台。
89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 0a 00 00 00 0a 08 06 00 00 00 8d 32 cf bd 00 00 00 04 73 42 49 54 08 08 08 08 7c 08 64 88 00 00 00 09 70 48 59 73 00 00 0d d7 00 00 0d d7 01 42 28 9b 78 00 00 00 19 74 45 58 74 53 6f ...
这是该示例的部分样本输出。
从 URL 读取
InputStream 允许从 URL 源读取数据。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URI;
import java.net.URISyntaxException;
void main() throws IOException, URISyntaxException {
String webSite = "https://www.something.com";
URL url = new URI(webSite).toURL();
try (InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
br.lines().forEach(System.out::println);
}
}
该示例打开到网页的 InputStream 并读取其数据。
try (InputStream is = url.openStream();
使用 openStream 方法创建到 URL 的 InputStream。
<html><head><title>Something.</title></head> <body>Something.</body> </html>
读取反序列化数据
ObjectInputStream 读取先前使用 ObjectOutputStream 写入的序列化数据。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
void main() throws IOException {
String fileName = "myfile.dat";
try (OutputStream fis = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fis)) {
List<Country> countries = new ArrayList<>();
countries.add(new Country("Slovakia", 5429000));
countries.add(new Country("Norway", 5271000));
countries.add(new Country("Croatia", 4225000));
countries.add(new Country("Russia", 143439000));
out.writeObject(countries);
}
}
record Country(String name, int population) implements Serializable {}
该示例序列化一个对象列表。
out.writeObject(countries);
国家/地区的列表写入到 ObjectOutputStream。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.List;
void main() throws IOException, ClassNotFoundException {
String fileName = "myfile.dat";
try (InputStream fis = new FileInputStream(fileName);
ObjectInputStream oin = new ObjectInputStream(fis)) {
List<Country> countries = (List<Country>) oin.readObject();
countries.forEach(System.out::println);
}
}
record Country(String name, int population) implements Serializable {}
我们使用 ObjectInputStream 读取序列化数据。
读取流序列
SequenceInputStream 表示输入流的序列。它允许从多个有序流中读取。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
void main() throws IOException {
String fileName1 = "myfile.txt";
String fileName2 = "myfile1.txt";
String fileName3 = "myfile2.txt";
try (InputStream is1 = new FileInputStream(fileName1);
InputStream is2 = new FileInputStream(fileName2);
InputStream is3 = new FileInputStream(fileName3);
SequenceInputStream sis1 = new SequenceInputStream(is1, is2);
SequenceInputStream sis = new SequenceInputStream(sis1, is3)) {
int b = sis.read();
while (b != -1) {
System.out.printf("%c", b);
b = sis.read();
}
System.out.println();
}
}
该示例从三个 FileInputStream 读取。
try (InputStream is1 = new FileInputStream(fileName1);
InputStream is2 = new FileInputStream(fileName2);
InputStream is3 = new FileInputStream(fileName3);
SequenceInputStream sis1 = new SequenceInputStream(is1, is2);
SequenceInputStream sis = new SequenceInputStream(sis1, is3)) {
我们定义了三个输入流,并将这些流放入 SequenceInputStreams 中。
int b = sis.read();
while (b != -1) {
System.out.printf("%c", b);
b = sis.read();
}
我们使用 read 从流中读取数据。
来源
在本文中,我们介绍了 Java InputStream 类。
作者
列出所有Java教程。