使用java代码从互联网下载图片的问题

时间:2012-05-17 03:18:33

标签: java download

以下代码无效:

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

下载的图片大小正确,但无法正常查看该图片的图片。我不知道诀窍在哪里。以下是我下载的图片 enter image description here

问题已解决,我的代码已更改为

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

3 个答案:

答案 0 :(得分: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();
     }

答案 1 :(得分: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);
        }

答案 2 :(得分: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

请参阅多线程问题。程序正在以错误的顺序将数据写入最终为损坏文件的文件。希望这很清楚。 这是作业吗?