我如何解析一个巨大的HTTPS可访问XML文件(使用Java&;Xerces),而不将其存储在本地?
在使用一些java代码下载一个非常大的XML文件时,我偶尔会看到这样的错误我如何解析一个巨大的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
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)。如果有一些简单的方法来呈现一致的输入流,从而打开新的连接以在引擎盖下恢复,那么这可能会解决问题。