6

Java で HTTP クエリをダウンロードしたいのですが、ダウンロードしたファイルの長さが不定です。

これは非常に標準的なものだと思ったので、検索してそのコード スニペットを見つけました: http://snipplr.com/view/33805/

しかし、contentLength 変数に問題があります。長さが不明なので、-1 を返します。これにより、エラーが発生します。contentLength に関するチェック全体を省略すると、常に最大バッファーを使用する必要があります。

しかし問題は、ファイルがまだ準備できていないことです。そのため、フラッシュは部分的にしか埋められず、ファイルの一部が失われます。

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)をダウンロードできるといいのですが。

4

1 に答える 1

19

これはうまくいくはずです、私はそれをテストしました、そしてそれは私のために働きます:

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
于 2013-01-19T11:41:13.870 に答える