使用 Java 通过 HTTP 下载未知长度的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14413774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Download file via HTTP with unknown length with Java
提问by sanderd17
I want to download a HTTP query with java, but the file I download has an undetermined length when downloading.
我想用java下载一个HTTP查询,但是我下载的文件在下载时长度不确定。
I thought this would be quite standard, so I searched and found a code snippet for it: http://snipplr.com/view/33805/
我认为这会很标准,所以我搜索并找到了它的代码片段:http: //snipplr.com/view/33805/
But it has a problem with the contentLength variable. As the length is unknown, I get -1 back. This creates an error. When I omit the entire check about contentLength, that means I always have to use the maximum buffer.
但是它的 contentLength 变量有问题。由于长度未知,我得到-1。这会产生错误。当我省略关于 contentLength 的整个检查时,这意味着我总是必须使用最大缓冲区。
But the problem is that the file is not ready yet. So the flush gets only partially filled, and parts of the file get lost.
但问题是文件还没有准备好。因此,flush 仅部分填充,部分文件丢失。
If you try downloading a link like http://overpass-api.de/api/interpreter?data=area%5Bname%3D%22Hoogstade%22%5D%3B%0A%28%0A++node%28area%29%3B%0A++%3C%3B%0A%29+%3B%0Aout+meta+qt%3Bwith that snippet, you'll notice the error, and when you always download the maximum buffer to omit the error, you end up with a corrupt XML file.
如果您尝试下载像http://overpass-api.de/api/interpreter?data=area%5Bname%3D%22Hoogstade%22%5D%3B%0A%28%0A++node%28area%29%这样的链接3B%0A++%3C%3B%0A%29+%3B%0Aout+meta+qt%3B使用该代码段,您会注意到错误,并且当您始终下载最大缓冲区以忽略错误时,您最终会得到损坏的 XML 文件。
Is there some way to only download the ready part of the file? I would like if this could download big files (up to a few GB).
有没有办法只下载文件的准备部分?我想这是否可以下载大文件(最多几 GB)。
回答by BackSlash
This should work, i tested it and it works for me:
这应该有效,我对其进行了测试,并且对我有效:
void downloadFromUrl(URL url, String localFilename) throws IOException {
InputStream is = null;
FileOutputStream fos = null;
try {
URLConnection urlConn = url.openConnection();//connect
is = urlConn.getInputStream(); //get connection inputstream
fos = new FileOutputStream(localFilename); //open outputstream to local file
byte[] buffer = new byte[4096]; //declare 4KB buffer
int len;
//while we have availble data, continue downloading and storing to local file
while ((len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
} finally {
try {
if (is != null) {
is.close();
}
} finally {
if (fos != null) {
fos.close();
}
}
}
}
If you want this to run in background, simply call it in a Thread:
如果您希望它在后台运行,只需在线程中调用它:
Thread download = new Thread(){
public void run(){
URL url= new URL("http://overpass-api.de/api/interpreter?data=area%5Bname%3D%22Hoogstade%22%5D%3B%0A%28%0A++node%28area%29%3B%0A++%3C%3B%0A%29+%3B%0Aout+meta+qt%3B");
String localFilename="mylocalfile"; //needs to be replaced with local file path
downloadFromUrl(url, localFilename);
}
};
download.start();//start the thread