假设我们有一些仅包含整数的二进制数据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首先击败了例外的目的。
使用Java Nio的IntBuffer
时,没有这样的问题。
IntBuffer in = ByteBuffer.wrap(data).asIntBuffer();
while (in.hasRemaining()){
int i = in.get();
}
来自C#并正在学习Java的过程中,我拒绝相信这是这样做的预期方法。
此外,i Just 遇到了Java Nio,这似乎是"非常新的"。相反,在这里使用IntBuffer
将是我拖延此事的方式。无论如何,我想知道在Java中正确完成此操作。
你不能。readInt()
可以返回任何整数值,因此需要一个频带的机制来发出流的信号,因此抛出了例外。这就是API的设计。您无能为力。
由于您来自.net,因此Java的DataInputStream
大致相当于.net的BinaryReader
。
就像它的.NET等效类别,DataInputStream
类及其主要接口DataInput
一样,没有规定确定是否可以在流的当前位置检索任何给定类型的原始类型。
您可以通过查看设计师自己对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
的数组序列化阵列中的项目数,该项目在循环len
次中调用readInt
(行2918)。