0

次のコードは機能していません。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DownloadFile extends Thread {

    URL url;
    long startPos;
    long endPos;
    int length;
    public static ExecutorService pool = Executors.newCachedThreadPool();

    public DownloadFile(URL url, long startPos, long endPos, int length) {
        this.url = url;
        this.startPos = startPos;
        this.endPos = endPos;
        this.length = length;
    }

    public static void main(String[] args) {
        try {
            download(new URL(
                    "http://hiphotos.baidu.com/dazhu1115/pic/item/fb8eccffa223a373d6887dfc.jpg"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void download(URL url) throws IOException {
        String fileName = url.getFile();
        final long size = 8096;
        if (fileName.equals("")) {
            throw new IOException("download webfile \"" + fileName
                    + "\" failed");
        }
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        long total = con.getContentLength();
        System.out.println("file size is " + total);
        con.disconnect();
        if (total <= size) {
            // con = (HttpURLConnection) url.openConnection();
            // con.connect();
            // in = con.getInputStream();
            // return download(fileName, in);
            // con.disconnect();
        } else {
            long part = total % size != 0 ? total / size + 1 : total / size;
            long len;
            byte[] b = null;
            for (int i = 0; i < part; i++) {
                len = i != part - 1 ? size : total % size;
                DownloadFile dl = new DownloadFile(url, size * i, size
                        * (i + 1), (int) len);
                pool.execute(dl);
            }
        }
    }

    public void run() {
        byte[] b = new byte[length];
        HttpURLConnection con;
        try {
            con = (HttpURLConnection) url.openConnection();
            con.setAllowUserInteraction(true);
            con.setReadTimeout(30000);
            con.setRequestProperty("RANGE", "bytes=" + startPos + "-" + endPos);
            // con.setRequestProperty("GET", fileName + " HTTP/1.1");
            // con.setRequestProperty("Accept","image/gif,image/x-xbitmap,application/msword");
            // con.setRequestProperty("Connection", "Keep-Alive");
            con.connect();
            /*
             * in = con.getInputStream(); DataInputStream dis = new
             * DataInputStream(in);
             */
            BufferedInputStream bis = new BufferedInputStream(
                    con.getInputStream());
            int wlen = bis.read(b, 0, length);
            RandomAccessFile oSavedFile = new RandomAccessFile("D:/bbb.jpg",
                    "rw");
            oSavedFile.seek(startPos);
            oSavedFile.write(b, 0, wlen);
            // con.disconnect();
            bis.close();
            oSavedFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ダウンロードした画像のサイズは正しいですが、この画像の画像を正しく表示できません。トリックがどこにあるのかわかりません。以下は私がダウンロードした画像です ここに画像の説明を入力してください

問題が解決し、コードを次のように変更しました

package com.tom.labs;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DownloadFile extends Thread {

    URL url;
    long startPos;
    long endPos;
    final static int bufferSize = 1024 * 3;
    public static ExecutorService pool = Executors.newCachedThreadPool();

    public DownloadFile(URL url, long startPos, long endPos) {
        this.url = url;
        this.startPos = startPos;
        this.endPos = endPos;
    }

    public static void main(String[] args) {
        try {
            download(new URL("http://hiphotos.baidu.com/dazhu1115/pic/item/fb8eccffa223a373d6887dfc.jpg"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void download(URL url) throws IOException {
        String fileName = url.getFile();
        final long size = 8096;
        if (fileName.equals("")) {
            throw new IOException("download webfile \"" + fileName + "\" failed");
        }
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        long total = con.getContentLength();
        System.out.println("file size is " + total);
        con.disconnect();
        if (total <= size) {

        } else {
            long part = total % size != 0 ? total / size + 1 : total / size;
            long len;
            byte[] b = null;
            for (int i = 0; i < part; i++) {
                len = i != part - 1 ? size : total % size;
                long startPos = size * i;
                long endPos = startPos + len - 1;
                con = (HttpURLConnection) url.openConnection();
                con.setAllowUserInteraction(true);
                con.setReadTimeout(30000);
                con.setRequestProperty("RANGE", "bytes=" + startPos + "-" + endPos);
                System.out.println("Request Data from " + startPos + " to " + endPos);
                con.connect();

                DownloadFile task = new DownloadFile(url,startPos,endPos);
                pool.execute(task);
            }
        }
    }

    public void run() {
        byte[] b = new byte[bufferSize];
        HttpURLConnection con;
        try {
            con = (HttpURLConnection) url.openConnection();
            con.setAllowUserInteraction(true);
            con.setReadTimeout(30000);
            con.setRequestProperty("RANGE", "bytes=" + startPos + "-" + endPos);
            con.connect();
            BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
            RandomAccessFile oSavedFile = new RandomAccessFile("D:/bbb.jpg", "rw");
            oSavedFile.seek(startPos);
            System.out.println("Request Data from " + startPos + " to " + endPos);
            while (startPos < endPos) {
                int wlen = bis.read(b, 0, bufferSize);
                oSavedFile.write(b, 0, wlen);
                startPos += wlen;
            }
            bis.close();
            oSavedFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4

3 に答える 3

1

私はファイルを抽出するために次のようなことをしました:

     String imgPath = "/* path to the URL on the internet */ "; 
     String imgFilePath = " /* path to file on disk */ ";

     URL imgUrl;
     try {
        imgUrl = new URL(imgPath);
        ReadableByteChannel rbc = Channels.newChannel(imgUrl.openStream());
        FileOutputStream fos = new FileOutputStream(imgFilePath);
        setState(EXTRACTING + imgFilePath);
        fos.getChannel().transferFrom(rbc, 0, 1 << 24);

     } catch (MalformedURLException e) {
        e.printStackTrace();
     } catch (FileNotFoundException e) {
        e.printStackTrace();
     } catch (IOException e) {
        e.printStackTrace();
     }
于 2012-05-17T03:25:05.940 に答える
1

使用BufferedIntpuStream.read可能なバイトがなくなるとメソッドが返されるため、ブロックサイズ全体を書き込むまでループする必要があります。

これがあなたの問題の修正です:

       BufferedInputStream bis = new BufferedInputStream(
                con.getInputStream());


        RandomAccessFile oSavedFile = new RandomAccessFile("D:/bbb.jpg",
                "rw");            
        oSavedFile.seek(startPos);
        int wlen = 0;
        while (wlen < length) {
            int read = bis.read(b, 0, length);
            wlen += read;
            oSavedFile.write(b, 0, read);
        }
于 2012-05-17T06:56:31.260 に答える
0

コードにローカルにいくつかのロギングステートメントを追加しました。以下はログです。

file size is 69635
Requesting data from position 0 to 8096
Requesting data from position 8096 to 16192
Requesting data from position 32384 to 40480
Requesting data from position 24288 to 32384
Requesting data from position 16192 to 24288
Requesting data from position 48576 to 56672
Requesting data from position 40480 to 48576
Requesting data from position 64768 to 72864
Requesting data from position 56672 to 64768
Writing data starting at 0
Writing data starting at 16192
Writing data starting at 24288
Writing data starting at 48576
Writing data starting at 40480
Writing data starting at 64768
Writing data starting at 56672
Writing data starting at 32384
Writing data starting at 8096

問題はマルチスレッドにあることを確認してください。プログラムは、破損したファイルとして終わるファイルに間違った順序でデータを書き込んでいます。これが十分に明確であることを願っています。これは宿題ですか?

于 2012-05-17T05:41:12.813 に答える