Java中DataInputStream读取未知大小的缓冲区

6
我有以下声明:
DataInputStream is = new DataInputStream(process.getInputStream());
我想打印这个输入流的内容,但我不知道这个流的大小。我应该如何读取这个流并将其打印出来?

如果你只使用缓冲区,使用DataInputStream并没有增加任何价值。 - Peter Lawrey
4个回答

8
所有流都有一个共同的特点,就是无法预先知道其长度。使用标准的InputStream时,通常的解决方法是直接调用read,直到返回-1为止。
但我想你之所以使用DataInputStream封装了一个标准的InputStream,一定是因为要解析二进制数据。(注意:Scanner只适用于文本数据。) DataInputStreamJavaDoc向你展示了这个类有两种不同的指示EOF的方式——每种方法要么返回-1,要么抛出EOFException异常。一条经验法则是:
  • 所有从InputStream继承而来的方法都使用“返回-1”的约定,
  • 所有没有InputStream继承而来的方法都会抛出EOFException异常。
例如,如果你使用readShort,可以一直读取直到抛出异常;如果你使用read(),那就一直读取直到返回-1 为止。
小贴士:在开始时要非常小心,查找你从DataInputStream使用的每个方法——一条经验法则可能会失效。

+1 这个教程详细解释了:"请注意,DataStreams通过捕获EOFException来检测文件结束的条件,而不是测试无效的返回值。" - trashgod
我认为我已经清楚地区分了DIS和IS。但是根据您的输入,我编辑了答案。谢谢。 - A.H.
哦,实现DataInput的方法(不是从InputStream继承的)会抛出EOFException。感谢澄清。 - trashgod

2

多次调用 is.read(byte[]) 方法,传入预先分配的缓冲区(可以重复使用同一缓冲区)。该函数将返回实际读取的字节数,或在流结束时返回-1(此时,请停止):

byte[] buf = new byte[8192];
int nread;
while ((nread = is.read(buf)) >= 0) {
  // process the first `nread` bytes of `buf`
}

1
byte[] buffer = new byte[100];
int numberRead = 0;
do{
   numberRead = is.read(buffer);
   if (numberRead != -1){
      // do work here
   }
}while (numberRead == buffer.length);

在循环中保持读取一定大小的缓冲区。如果返回值小于缓冲区大小,那么你就知道已经到达了流的末尾。如果返回值为-1,则表示缓冲区中没有数据。

DataInputStream.read


-1

DataInputStream 已经过时了。我建议您使用 Scanner

Scanner sc = new Scanner (process.getInputStream());
while (sc.hasNextXxx()) {
   System.out.println(sc.nextXxx());
}

不确定DataInputStream是否已经过时了,但它在这里是多余的。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接