2010-11-07 102 views
3

我试图连接到服务器,然后发送一个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中正确读取它。如果是二进制文件,我声明一个字节[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和所有这些。这不是问题。

回答

3

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

如果你知道如何使用URLConnection,我不知道你有什么理由不使用它。

+0

啊!我认为这是重点。我将尝试使用InputStream来读取头文件。还是有另一个更好的解决方案?我只是想了解HTTP如何工作,这不适用于任何“专业”使用,这就是为什么我不使用URLConnection;) – 2010-11-07 16:04:05

+0

我会做以下事情:首先,我会从流和缓冲区读取,直到我请参阅HTTP响应标头的末尾(“\ r \ n \ r \ n”)。这将是响应标题。您可以使用ASCII编码将其解码为字符串,然后解析它以获取内容长度。然后,发出另一个读取内容长度字节的流。 – feroze 2010-11-07 17:59:20

1

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

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

+0

我只使用BufferedReader作为头文件和HTML文件,而不是二进制数据。 – 2010-11-07 16:05:44