从套接字读取二进制数据

时间:2010-11-07 12:57:18

标签: java http sockets get

我正在尝试连接到服务器,然后向它发送HTTP请求(在这种情况下为GET)。想法是请求一个文件,然后从服务器接收它。

它应该适用于文本文件和二进制文件(例如imgs)。我对文本文件没有任何问题,它工作得很完美,但我遇到了二进制文件的麻烦。

首先,我声明一个BufferedReader(用于读取头文件和文本文件)和一个DataInput流:

BufferedReader in_text = new BufferedReader(
    new InputStreamReader(socket.getInputStream()));

DataInputStream in_binary = new DataInputStream(
    new BufferedInputStream(socket.getInputStream()));

然后,我用in_text读取标题并发现它是文本文件还是二进制文件。如果它是一个文本文件,我在StringBuilder中正确读取它。如果它是二进制文件,我声明一个byte [filesize]并存储in_binary的以下内容。

byte[] bindata = new byte[filesize];
in_binary.readFully(bindata);

它不起作用。我收到了EOFException。

我认为也许in_binary仍然在流的第一个位置,所以它还没有读取标题。所以我捕获了标题的长度并跳过in_binary中的字节。

byte[] bindata = new byte[filesize];
in_binary.reset();
in_binary.skip(headersize);
in_binary.readFully(bindata);

还是一样。

可能会发生什么?

谢谢!

PD:我知道我可以使用URLConnection和所有这些。那不是问题。

2 个答案:

答案 0 :(得分:3)

BufferedReader缓冲数据(因此名称) - 它几乎肯定会从套接字读取更多数据而不仅仅是标题。因此,当您尝试读取实际数据时,已从插槽中读取了一些数据。如果您尝试只读取几个字节,您可能会发现它们不是实际响应数据的第一个字节。

如果您知道如何使用URLConnection,我不得不怀疑您不使用它的原因。

答案 1 :(得分:1)

只要使用Reader的任何子类,就不会读二进制文件。您正在使用JVM的默认编码从字节转换为字符。如果你真的想要二进制字节,你需要坚持使用流而不是读者。一次创建两个堆栈就会遇到麻烦。

使用Apache Commons IO:IOUtils.toByteArray()将整个内容作为byte []读入内存,然后决定如何处理它,除非你有大量的数据,在这种情况下你应该设置在缓冲的输入流中,确定要做什么,并且只在你推回后构建阅读器。