Скачать файл, используя Java Apache Commons? - PullRequest
13 голосов
/ 15 января 2011

Как я могу использовать библиотеку, чтобы загрузить файл и распечатать сохраненные байты?Я попытался использовать

import static org.apache.commons.io.FileUtils.copyURLToFile;
public static void Download() {

        URL dl = null;
        File fl = null;
        try {
            fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
            dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
            copyURLToFile(dl, fl);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

, но не могу отобразить байты или индикатор выполнения.Какой метод я должен использовать?

public class download {
    public static void Download() {
        URL dl = null;
        File fl = null;
        String x = null;
        try {
            fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
            dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
            OutputStream os = new FileOutputStream(fl);
            InputStream is = dl.openStream();
            CountingOutputStream count = new CountingOutputStream(os);
            dl.openConnection().getHeaderField("Content-Length");
            IOUtils.copy(is, os);//begin transfer

            os.close();//close streams
            is.close();//^
        } catch (Exception e) {
            System.out.println(e);
        }
    }

Ответы [ 2 ]

13 голосов
/ 15 января 2011

Если вы ищете способ получить общее количество байтов перед загрузкой, вы можете получить это значение из заголовка Content-Length в HTTP-ответе.

Если вы просто хотите получить окончательное количество байтовпосле загрузки проще всего проверить размер файла, в который вы просто записываете.

Однако, если вы хотите отобразить текущий прогресс в количестве загруженных байтов, вы можете расширить apache CountingOutputStream доОберните FileOutputStream, чтобы при каждом вызове методов write он подсчитывал количество проходящих байтов и обновлял индикатор выполнения.

Обновление

Здесьпростая реализация DownloadCountingOutputStream.Я не уверен, знакомы ли вы с использованием ActionListener или нет, но это полезный класс для реализации GUI.

public class DownloadCountingOutputStream extends CountingOutputStream {

    private ActionListener listener = null;

    public DownloadCountingOutputStream(OutputStream out) {
        super(out);
    }

    public void setListener(ActionListener listener) {
        this.listener = listener;
    }

    @Override
    protected void afterWrite(int n) throws IOException {
        super.afterWrite(n);
        if (listener != null) {
            listener.actionPerformed(new ActionEvent(this, 0, null));
        }
    }

}

Это пример использования:

public class Downloader {

    private static class ProgressListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            // e.getSource() gives you the object of DownloadCountingOutputStream
            // because you set it in the overriden method, afterWrite().
            System.out.println("Downloaded bytes : " + ((DownloadCountingOutputStream) e.getSource()).getByteCount());
        }
    }

    public static void main(String[] args) {
        URL dl = null;
        File fl = null;
        String x = null;
        OutputStream os = null;
        InputStream is = null;
        ProgressListener progressListener = new ProgressListener();
        try {
            fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
            dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
            os = new FileOutputStream(fl);
            is = dl.openStream();

            DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
            dcount.setListener(progressListener);

            // this line give you the total length of source stream as a String.
            // you may want to convert to integer and store this value to
            // calculate percentage of the progression.
            dl.openConnection().getHeaderField("Content-Length");

            // begin transfer by writing to dcount, not os.
            IOUtils.copy(is, dcount);

        } catch (Exception e) {
            System.out.println(e);
        } finally {
            IOUtils.closeQuietly(os);
            IOUtils.closeQuietly(is);
        }
    }
}
11 голосов
/ 15 января 2011

commons-io имеет IOUtils.copy(inputStream, outputStream). Итак:

OutputStream os = new FileOutputStream(fl);
InputStream is = dl.openStream();

IOUtils.copy(is, os);

И IOUtils.toByteArray(is) могут использоваться для получения байтов.

Получение общего количества байтов - это отдельная история. Потоки не дают вам всего - они могут дать вам только то, что в данный момент доступно в потоке. Но так как это поток, он может быть еще больше.

Вот почему в http есть особый способ указания общего количества байтов. Он находится в заголовке ответа Content-Length. Поэтому вам нужно будет позвонить url.openConnection(), а затем getHeaderField("Content-Length") для объекта URLConnection. Он вернет количество байтов в виде строки. Затем используйте Integer.parseInt(bytesString), и вы получите свою общую сумму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...