【问题标题】:Download file via HTTP with unknown length with Java使用 Java 通过 HTTP 下载长度未知的文件
【发布时间】:2013-01-19 11:17:49
【问题描述】:

我想用 java 下载一个 HTTP 查询,但是我下载的文件在下载时长度不确定。

我觉得这会很标准,所以我搜索并找到了它的代码sn-p:http://snipplr.com/view/33805/

但是 contentLength 变量有问题。由于长度未知,我得到-1。这会产生错误。当我省略对 contentLength 的整个检查时,这意味着我总是必须使用最大缓冲区。

但问题是文件还没有准备好。因此,flush 仅被部分填充,部分文件丢失。

如果您尝试使用该 sn-p 下载像 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 文件。

有没有办法只下载文件的就绪部分?我希望这可以下载大文件(最多几 GB)。

【问题讨论】:

    标签: java http download


    【解决方案1】:

    这应该可以,我测试过它对我有用:

    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();
                }
            }
        }
    }
    

    如果您希望它在后台运行,只需在线程中调用它:

    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
    

    【讨论】:

    • 我注意到真正的问题是 file.seek 命令在这种情况下无法正常工作。它没有找到文件的结尾,因此覆盖了其中的一部分。使用 FileOutputStream 修复它(在摆脱错误代码之后,就像我已经完成的那样)。
    猜你喜欢
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    相关资源
    最近更新 更多