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 回答