使用 java apache commons 下载文件?

发布于 2024-10-12 07:07:55 字数 1359 浏览 5 评论 0原文

如何使用该库下载文件并打印保存的字节?我尝试使用

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

How can I use the library to download a file and print out bytes saved? I tried using

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

but I cannot display bytes or a progress bar. Which method should I use?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若有似无的小暗淡 2024-10-19 07:07:55

如果您正在寻找一种在下载前获取总字节数的方法,您可以从 http 响应中的 Content-Length 标头获取此值。

如果您只想要下载后的最终字节数,最简单的方法是检查刚刚写入的文件大小。

但是,如果您想显示已下载字节数的当前进度,您可能需要扩展 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);
        }
    }
}

If you are looking for a way to get the total number of bytes before downloading, you can obtain this value from the Content-Length header in http response.

If you just want the final number of bytes after the download, it is easiest to check the file size you just write to.

However if you want to display the current progress of how many bytes have been downloaded, you might want to extend apache CountingOutputStream to wrap the FileOutputStream so that everytime the write methods are called it counts the number of bytes passing through and update the progress bar.

Update

Here is a simple implementation of DownloadCountingOutputStream. I am not sure if you are familiar with using ActionListener or not but it is a useful class for implementing 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));
        }
    }

}

This is the usage sample :

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);
        }
    }
}
绅刃 2024-10-19 07:07:55

commons-ioIOUtils.copy(inputStream,outputStream)。所以:

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

IOUtils.copy(is, os);

并且可以使用 IOUtils.toByteArray(is) 来获取字节。

获取总字节数是另一回事。流不会为您提供任何总数 - 它们只能为您提供流中当前可用的内容。但既然它是一个流,它可以有更多的东西。

这就是为什么 http 有其特殊的方式来指定总字节数。它位于响应标头 Content-Length 中。因此,您必须调用 url.openConnection(),然后对 URLConnection 对象调用 getHeaderField("Content-Length")。它将以字符串形式返回字节数。然后使用 Integer.parseInt(bytesString) 即可得到总数。

commons-io has IOUtils.copy(inputStream, outputStream). So:

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

IOUtils.copy(is, os);

And IOUtils.toByteArray(is) can be used to get the bytes.

Getting the total number of bytes is a different story. Streams don't give you any total - they can only give you what is currently available in the stream. But since it's a stream, it can have more coming.

That's why http has its special way of specifying the total number of bytes. It is in the response header Content-Length. So you'd have to call url.openConnection() and then call getHeaderField("Content-Length") on the URLConnection object. It will return the number of bytes as string. Then use Integer.parseInt(bytesString) and you'll get your total.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文