Java DataInputStream 类
最后修改时间:2025 年 4 月 16 日
java.io.DataInputStream
类允许从底层输入流中读取 Java 原始数据类型。它以一种与机器无关的方式读取数据。这对于读取由 DataOutputStream
写入的数据非常有用。
DataInputStream
实现了 DataInput
接口。它封装了另一个 InputStream
并提供了读取原始数据类型的方法。在没有外部同步的情况下,该类不是线程安全的,不适合并发访问。
DataInputStream 类概述
DataInputStream
继承了 FilterInputStream
并提供了读取 Java 原始数据类型的方法。 关键方法包括读取各种数据类型,如 int、double、boolean 等。所有方法都以大端格式读取数据。
public class DataInputStream extends FilterInputStream implements DataInput { public DataInputStream(InputStream in); public final int read(byte[] b) throws IOException; public final int read(byte[] b, int off, int len) throws IOException; public final boolean readBoolean() throws IOException; public final byte readByte() throws IOException; public final char readChar() throws IOException; public final double readDouble() throws IOException; public final float readFloat() throws IOException; public final int readInt() throws IOException; public final long readLong() throws IOException; public final short readShort() throws IOException; public final String readUTF() throws IOException; public final int readUnsignedByte() throws IOException; public final int readUnsignedShort() throws IOException; public final int skipBytes(int n) throws IOException; }
上面的代码显示了 DataInputStream
提供的关键方法。 这些方法允许从流中读取原始数据类型。如果意外到达流的末尾,读取方法会抛出 EOFException
。
创建 DataInputStream
DataInputStream 是通过将其封装在另一个 InputStream
中创建的。通常与文件或网络流一起使用。构造函数将底层流作为参数。完成后始终关闭流。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try { // Create with FileInputStream FileInputStream fileStream = new FileInputStream("data.bin"); DataInputStream dataStream = new DataInputStream(fileStream); System.out.println("DataInputStream created successfully"); dataStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示如何从 FileInputStream
创建 DataInputStream
。使用后应正确关闭流。try-with-resources 语句也可用于自动资源管理。
读取原始数据类型
DataInputStream 提供了读取所有 Java 原始类型的方法。 每种方法读取该类型所需的字节数。 如果到达流的末尾,这些方法会抛出 EOFException
。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("primitives.dat"))) { boolean boolVal = dis.readBoolean(); byte byteVal = dis.readByte(); char charVal = dis.readChar(); double doubleVal = dis.readDouble(); float floatVal = dis.readFloat(); int intVal = dis.readInt(); long longVal = dis.readLong(); short shortVal = dis.readShort(); System.out.println("Boolean: " + boolVal); System.out.println("Byte: " + byteVal); System.out.println("Char: " + charVal); System.out.println("Double: " + doubleVal); System.out.println("Float: " + floatVal); System.out.println("Int: " + intVal); System.out.println("Long: " + longVal); System.out.println("Short: " + shortVal); } catch (IOException e) { e.printStackTrace(); } } }
此示例从文件中读取各种原始类型。 数据必须使用 DataOutputStream
以相同的顺序写入。 读取方法期望数据采用大端格式。每种方法都精确读取该类型所需的字节数。
读取 UTF 字符串
readUTF
方法读取以修改后的 UTF-8 格式编码的字符串。 这与 DataOutputStream.writeUTF
使用的格式相同。 前两个字节表示字符串长度,后跟字符串数据。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("strings.dat"))) { String str1 = dis.readUTF(); String str2 = dis.readUTF(); System.out.println("First string: " + str1); System.out.println("Second string: " + str2); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示如何从文件读取 UTF-8 编码的字符串。 这些字符串必须已使用 DataOutputStream.writeUTF
写入。 该方法首先读取长度,然后读取字符串字节。修改后的 UTF-8 处理空字符的方式与标准 UTF-8 不同。
读取字节数组
DataInputStream 提供了读取字节数组的方法。 readFully
方法读取直到缓冲区已满或到达流的末尾。 这些对于读取固定大小的二进制数据非常有用。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("bytes.dat"))) { byte[] buffer = new byte[100]; // Read exactly 100 bytes dis.readFully(buffer); System.out.println("Read " + buffer.length + " bytes"); // Read into part of array byte[] partialBuffer = new byte[200]; dis.readFully(partialBuffer, 50, 100); System.out.println("Read 100 bytes into offset 50"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了如何使用 readFully
读取字节数组。 第一次调用读取一个完整的 100 字节数组。 第二次调用将 100 个字节读取到从偏移量 50 开始的 200 字节数组中。 如果在填充缓冲区之前到达流的末尾,这些方法会抛出 EOFException
。
跳过字节
skipBytes
方法尝试跳过指定数量的字节。 它返回跳过的实际字节数。 如果到达流的末尾,则可能小于请求的字节数。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) { System.out.println("Available bytes: " + dis.available()); int skipped = dis.skipBytes(50); System.out.println("Skipped " + skipped + " bytes"); // Read after skipping int value = dis.readInt(); System.out.println("Read int after skipping: " + value); // Try to skip beyond end skipped = dis.skipBytes(1000); System.out.println("Skipped " + skipped + " bytes (end near)"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示如何在流中跳过字节。 第一次跳过向前移动 50 个字节。 第二次尝试跳过 1000 个字节,但如果在接近末尾时可能会跳过较少的字节。 available
方法显示剩余字节数,但对于所有流类型并非总是准确的。
读取无符号值
DataInputStream 提供了读取无符号字节和短整型值的方法。 这些返回的值采用更大的类型 (int) 以适应无符号范围。 在使用使用无符号值的二进制格式时很有用。
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (DataInputStream dis = new DataInputStream(new FileInputStream("unsigned.dat"))) { int unsignedByte = dis.readUnsignedByte(); int unsignedShort = dis.readUnsignedShort(); System.out.println("Unsigned byte: " + unsignedByte); System.out.println("Unsigned short: " + unsignedShort); // Regular read for comparison byte signedByte = dis.readByte(); short signedShort = dis.readShort(); System.out.println("Signed byte: " + signedByte); System.out.println("Signed short: " + signedShort); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了如何读取无符号值。 无符号字节方法在 int 中返回 0-255。 无符号 short 返回 0-65535。 与可能返回负值的有符号读取进行比较。 在处理使用无符号值的二进制格式时很有用。
来源
在本文中,我们介绍了 Java DataInputStream 类的基本方法和特性。 了解这些概念对于在 Java I/O 操作中使用二进制数据和原始类型至关重要。
作者
列出所有Java教程。