Java DataInput 接口
最后修改时间:2025 年 4 月 16 日
java.io.DataInput
接口提供了从输入流读取二进制数据的方法。 它定义了以与机器无关的方式读取基本类型和字符串的操作。 实现此接口的类可以读取由 DataOutput
实现写入的数据。
DataInput
由 DataInputStream
和 RandomAccessFile
等类实现。 该接口确保了数据读取的一致性,而与底层平台无关。 默认情况下,所有方法都以大端格式读取数据。
DataInput 接口概述
DataInput
接口包含读取基本类型和字符串的方法。 它包括读取字节、布尔值、字符和其他数据类型的方法。 该接口还提供了读取 UTF-8 编码字符串的方法。
public interface DataInput { void readFully(byte[] b) throws IOException; void readFully(byte[] b, int off, int len) throws IOException; int skipBytes(int n) throws IOException; boolean readBoolean() throws IOException; byte readByte() throws IOException; int readUnsignedByte() throws IOException; short readShort() throws IOException; int readUnsignedShort() throws IOException; char readChar() throws IOException; int readInt() throws IOException; long readLong() throws IOException; float readFloat() throws IOException; double readDouble() throws IOException; String readLine() throws IOException; String readUTF() throws IOException; }
上面的代码显示了完整的 DataInput
接口。 每个方法都从输入流中读取特定的数据类型。 该接口会为任何 I/O 错误抛出 IOException
。 如果到达流的末尾,某些方法可能会抛出 EOFException
。
使用 DataInputStream 读取基本类型
DataInputStream
是 DataInput
最常见的实现。 它封装了一个 InputStream
并提供了读取基本类型的方法。 此示例展示了如何读取不同的数据类型。
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"))) { // Read different data types boolean boolVal = dis.readBoolean(); byte byteVal = dis.readByte(); char charVal = dis.readChar(); short shortVal = dis.readShort(); int intVal = dis.readInt(); long longVal = dis.readLong(); float floatVal = dis.readFloat(); double doubleVal = dis.readDouble(); System.out.println("Boolean: " + boolVal); System.out.println("Byte: " + byteVal); System.out.println("Char: " + charVal); System.out.println("Short: " + shortVal); System.out.println("Int: " + intVal); System.out.println("Long: " + longVal); System.out.println("Float: " + floatVal); System.out.println("Double: " + doubleVal); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了从二进制文件读取基本类型。 数据必须以写入时的相同顺序读取。 DataInputStream
会自动将字节转换为适当的基本类型。 try-with-resources 语句确保正确关闭流。
使用 readFully 读取字节数组
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("binary.dat"))) { // Read fixed-size header byte[] header = new byte[16]; dis.readFully(header); System.out.println("Header read: " + new String(header)); // Read data with offset byte[] data = new byte[1024]; dis.readFully(data, 0, 512); // Read first half dis.readFully(data, 512, 512); // Read second half System.out.println("Data read successfully"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了 readFully
的两个变体。 第一个读取完整的字节数组,而第二个读取数组的一部分。 如果在读取所有字节之前到达流的末尾,这两个方法都会抛出 EOFException
。 它们对于读取固定大小的数据结构非常有用。
读取 UTF-8 字符串
readUTF
方法读取以修改后的 UTF-8 格式编码的字符串。 此格式以一个两字节的长度开头,后跟字符串字节。 它通常用于序列化和网络通信。
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"))) { // Read UTF string String str1 = dis.readUTF(); System.out.println("First string: " + str1); // Read another UTF string String str2 = dis.readUTF(); System.out.println("Second string: " + str2); // Read remaining strings while (dis.available() > 0) { System.out.println("Next string: " + dis.readUTF()); } } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了从二进制文件读取 UTF-8 编码的字符串。 readUTF
方法首先读取长度,然后读取字符串字节。 available
方法检查剩余数据。 请注意,由 DataOutput
写入的 UTF-8 字符串使用与标准 UTF-8 不同的修改后的格式。
跳过流中的字节
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("datafile.dat"))) { // Read first value int firstValue = dis.readInt(); System.out.println("First value: " + firstValue); // Skip 8 bytes int skipped = dis.skipBytes(8); System.out.println("Skipped " + skipped + " bytes"); // Read next value after skip double nextValue = dis.readDouble(); System.out.println("Next value: " + nextValue); // Try to skip beyond end of file skipped = dis.skipBytes(1000); System.out.println("Skipped " + skipped + " bytes at end"); } catch (IOException e) { e.printStackTrace(); } } }
此示例展示了如何在数据流中跳过字节。 第一个跳过移动到两个值之间的 8 个字节。 第二个跳过尝试跳过 1000 个字节,但仅跳过剩余的字节。 该方法返回实际跳过的字节数,该数量可能少于文件末尾请求的数量。
读取无符号值
DataInput
提供了读取无符号字节和短整型值的方法。 这些在处理使用无符号类型的二进制数据时非常有用。 Java 没有无符号基本类型,因此这些方法返回更宽的类型。
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"))) { // Read unsigned byte (0-255) int unsignedByte = dis.readUnsignedByte(); System.out.println("Unsigned byte: " + unsignedByte); // Read unsigned short (0-65535) int unsignedShort = dis.readUnsignedShort(); System.out.println("Unsigned short: " + unsignedShort); // Read signed and unsigned comparison byte signedByte = dis.readByte(); int anotherUnsigned = dis.readUnsignedByte(); System.out.println("Signed byte: " + signedByte); System.out.println("Unsigned byte: " + anotherUnsigned); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了读取无符号值。 readUnsignedByte
返回一个 0-255 范围内的 int,而 readUnsignedShort
返回 0-65535。 该示例显示了有符号和无符号字节值之间的区别。 这些方法在处理使用无符号类型的二进制格式时至关重要。
使用 readLine 读取行
readLine
方法读取以换行符、回车符或 EOF 终止的文本行。 它已被弃用,但对于遗留格式仍然有用。 现代代码应首选 readUTF
或其他文本读取方法。
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("textfile.txt"))) { // Read lines until EOF String line; while ((line = dis.readLine()) != null) { System.out.println("Line read: " + line); } System.out.println("End of file reached"); } catch (IOException e) { e.printStackTrace(); } } }
此示例展示了如何使用已弃用的 readLine
方法。 它读取行,直到遇到 null (EOF)。 对于非 ASCII 文本,该方法无法正确地将字节转换为字符。 对于现代代码,请改用 BufferedReader.readLine
进行正确的文本处理。
来源
在本文中,我们通过实际示例介绍了 Java DataInput 接口的所有方法。 了解这些方法对于在 Java 应用程序中使用二进制数据至关重要。
作者
列出所有Java教程。