我如何解析一个巨大的HTTPS可访问XML文件(使用Java&;Xerces),而不将其存储在本地?

我如何解析一个巨大的HTTPS可访问XML文件(使用Java&;Xerces),而不将其存储在本地?,java,https,network-programming,Java,Https,Network Programming,在使用一些java代码下载一个非常大的XML文件时,我偶尔会看到这样的错误 Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[205648765,55] Message: SSL peer shut down incorrectly at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamRead

在使用一些java代码下载一个非常大的XML文件时,我偶尔会看到这样的错误

Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[205648765,55]
Message: SSL peer shut down incorrectly
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:596)
我想象那里发生的事情是,web服务器决定终止已打开超过X小时的连接(这是一个非常大的xml文件),这显然会给我一个被截断的流,从而导致解析器错误

我如何避免这个问题,而不用像wget这样可以重试的东西来获取整个文件?(例如,假设文件可能比本地磁盘大)


注意-我可以看到服务器支持范围请求,因此一个可能的解决方案似乎是使用InputStream实现,该实现捕获错误,从它得到的最后一个字节开始打开一个新连接,然后继续。或者,也许有一种我不知道的方法,可以让XML解析器处理文件的块,而不是输入流。

在没有更好的答案的情况下,这里是一个解决方案的经过黑客攻击、未经测试、第一次剪切的版本

如果有相同概念的经过测试的版本,我还是很想知道

package httpstreamresumer;

import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicHeader;

public class ResumingHttpStream extends InputStream {

    private long lastByte = -1;
    private String url;
    private HttpClient httpClient;

    private InputStream currentStream;

    public ResumingHttpStream(HttpClient httpClient, String url) throws ClientProtocolException, IOException {
        this.url = url;
        this.httpClient = httpClient;
        rebuildCurrentStream();
    }

    private void rebuildCurrentStream() throws ClientProtocolException, IOException {
        HttpGet httpRequest = new HttpGet(url);

        HttpResponse response;
        if (lastByte > 0) {
            httpRequest.addHeader(new BasicHeader("Range", "bytes=" + (lastByte + 1) + "-"));

            response = httpClient.execute(httpRequest);

            if (response.getStatusLine().getStatusCode() != 206) {
                throw new UnsupportedOperationException("Expected 206 response code, but got " + response.getStatusLine().getStatusCode() +" - Looks like the server doen't support Range requests");
            }
        } else {
            response = httpClient.execute(httpRequest);            
        }

        currentStream = response.getEntity().getContent();        
    }

    @Override
    public int read() throws IOException {
        int nextByte;
        try {
            nextByte = currentStream.read();
        } catch (IOException e) {
            rebuildCurrentStream();
            nextByte = currentStream.read();
            // If we fail twice without progressing, we probably need to give up
        }
        lastByte++;
        return nextByte;
    }

}

嗯,五个视图中有两个非主题接近投票…我想是因为我要求图书馆推荐?也许我应该重新措辞,要求实现,然后等待有人说‘不要自己写,使用XYZ!’:)-嗯,好吧,那么也许只是“我应该如何使用Xerces解析一个巨大的XML文件(通过HTTPS访问),而不必首先在本地存储整个文件?”…可能太晚了,无法从-2上保存此文件,反正它是开着的。我想……你是在问如何在线解析一个需要很长时间才能在线发送和解析的XML文件。当然,您理解这在术语上是矛盾的?好吧,假设服务器支持范围标头(它支持),就有可能在多个请求中获取它,问题是,您不能轻易地让XML解析器处理多个块(AFAIK)。如果有一些简单的方法来呈现一致的输入流,从而打开新的连接以在引擎盖下恢复,那么这可能会解决问题。