使用java apache commons下载文件?

2022-09-04 08:06:52

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

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

答案 1

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

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

但是,如果要显示已下载了多少字节的当前进度,则可能需要扩展 apache 以包装 ,以便每次调用方法时,它都会计算通过的字节数并更新进度条。CountingOutputStreamFileOutputStreamwrite

更新

下面是 的简单实现。我不确定你是否熟悉使用,但它是实现GUI的有用类。DownloadCountingOutputStreamActionListener

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

答案 2

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

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

IOUtils.copy(is, os);

并且可用于获取字节。IOUtils.toByteArray(is)

获取总字节数是另一回事。流不会给你任何总数 - 它们只能给你流中当前可用的内容。但是由于它是一个流,它可以有更多的来临。

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


推荐