如何在不需要捕获 EOFException 的情况下读取 DataInputStream 直到结束?
How to read DataInputStream until the end without needing to catch an EOFException?
假设我们有一些只包含整数的二进制数据byte[] data
。如果我想使用 DataInputStream
读取此数据,我唯一能想到的方法如下:
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
try {
while (true){
int i = in.readInt();
}
} catch (EOFException e) {
// we're done!
} catch (IOException e){
throw new RuntimeException(e);
}
让我感到困扰的是,到达流的末尾是预期的,只有在没有抛出异常的情况下才会异常,IMO破坏了异常的目的第一名.
使用JavaNIO的IntBuffer
时,没有这个问题
IntBuffer in = ByteBuffer.wrap(data).asIntBuffer();
while (in.hasRemaining()){
int i = in.get();
}
来自 C# 并且正在学习 Java 我拒绝相信这是这样做的预期方式。
另外,我刚刚遇到了Java NIO,好像是"quite new"。在这里使用 IntBuffer
将是我拖延此事的方式。无论如何,我想知道如何在 Java.
中正确完成此操作
你不能。 readInt()
可以 return 任何整数值,因此需要带外机制来指示流结束,因此会抛出异常。 API 就是这样设计的。你对此无能为力。
由于您来自 .NET,Java 的 DataInputStream
is roughly equivalent to BinaryReader
of .NET。
就像它的 .NET 等效项一样,DataInputStream
class 及其主界面 DataInput
没有规定确定任何给定类型的基元是否可用于检索流的当前位置。
通过查看设计者自己对 API 的使用,您可以获得有关 API 的设计者希望您如何使用它的宝贵见解。
例如,查看ObjectInputStream.java
源,它用于对象反序列化。读取各种类型数组的代码在循环中调用 DataInput
的特定于类型的 readXYZ
方法。为了弄清楚基元在哪里结束,代码检索了项目的数量(第 1642 行):
private Object readArray(boolean unshared) throws IOException {
if (bin.readByte() != TC_ARRAY) {
throw new InternalError();
}
ObjectStreamClass desc = readClassDesc(false);
int len = bin.readInt();
...
if (ccl == Integer.TYPE) {
bin.readInts((int[]) array, 0, len);
...
}
...
}
上面,bin
是一个BlockDataInputStream
,是DataInput
接口的另一种实现。请注意 len
,数组序列化对应项存储的数组中的项数,如何传递给 readInts
,后者在循环中调用 readInt
len
次(第 2918 行) .
假设我们有一些只包含整数的二进制数据byte[] data
。如果我想使用 DataInputStream
读取此数据,我唯一能想到的方法如下:
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
try {
while (true){
int i = in.readInt();
}
} catch (EOFException e) {
// we're done!
} catch (IOException e){
throw new RuntimeException(e);
}
让我感到困扰的是,到达流的末尾是预期的,只有在没有抛出异常的情况下才会异常,IMO破坏了异常的目的第一名.
使用JavaNIO的IntBuffer
时,没有这个问题
IntBuffer in = ByteBuffer.wrap(data).asIntBuffer();
while (in.hasRemaining()){
int i = in.get();
}
来自 C# 并且正在学习 Java 我拒绝相信这是这样做的预期方式。
另外,我刚刚遇到了Java NIO,好像是"quite new"。在这里使用 IntBuffer
将是我拖延此事的方式。无论如何,我想知道如何在 Java.
你不能。 readInt()
可以 return 任何整数值,因此需要带外机制来指示流结束,因此会抛出异常。 API 就是这样设计的。你对此无能为力。
由于您来自 .NET,Java 的 DataInputStream
is roughly equivalent to BinaryReader
of .NET。
就像它的 .NET 等效项一样,DataInputStream
class 及其主界面 DataInput
没有规定确定任何给定类型的基元是否可用于检索流的当前位置。
通过查看设计者自己对 API 的使用,您可以获得有关 API 的设计者希望您如何使用它的宝贵见解。
例如,查看ObjectInputStream.java
源,它用于对象反序列化。读取各种类型数组的代码在循环中调用 DataInput
的特定于类型的 readXYZ
方法。为了弄清楚基元在哪里结束,代码检索了项目的数量(第 1642 行):
private Object readArray(boolean unshared) throws IOException {
if (bin.readByte() != TC_ARRAY) {
throw new InternalError();
}
ObjectStreamClass desc = readClassDesc(false);
int len = bin.readInt();
...
if (ccl == Integer.TYPE) {
bin.readInts((int[]) array, 0, len);
...
}
...
}
上面,bin
是一个BlockDataInputStream
,是DataInput
接口的另一种实现。请注意 len
,数组序列化对应项存储的数组中的项数,如何传递给 readInts
,后者在循环中调用 readInt
len
次(第 2918 行) .