我正在编写一个从特定站点下载mp3列表的刮板(1,700多个mp3,每个15 MB)。给我的方法一个URL的List和一个目标文件夹。

我想围绕它编写一个JProgressBar对话框,该对话框具有:


当前的传输速率。
当前正在下载的文件信息(完成了多少/剩余了多少)。


我使用的是转移到ReadableByteChannelFileOutputStream(或更准确地说,是从RBC转移的FOS)。

这是代码:

private static void download(List<String> mp3_urls, String directory) {
    try {
        for(String mp3_url : mp3_urls) {
            URL url = new URL(mp3_url);
            try (ReadableByteChannel rbc = Channels.newChannel(url.openStream());) {
                Pattern pattern = Pattern.compile("[A-Za-z0-9_]*\\.mp3");
                Matcher matcher = pattern.matcher(mp3_url);
                matcher.find();

                System.out.println("Reading: " + mp3_url);
                try (FileOutputStream fos = new FileOutputStream(directory + File.separator + matcher.group())) {
                    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}


我的问题是:


FileOutputStream::transferFrom方法是否抛出任何可能提供此信息的PropertyChangeListener捕获的属性?
我是否使用能够提供此信息的方法?
您将如何获得此信息?

最佳答案

您错过了重点。理想情况下,transferFrom()发生在内核中,根本不需要咨询应用程序。这就是重点。您需要进度指示(可以通过套接字或ProgressMonitorInputStream输入流周围的URLConnection获得),或者需要快速的内核模式副本。不能两者兼有。

注意:


方法是FileChannel.transferFrom(),而不是FileOutputStream::transferFrom().
一个电话是不够的。你必须循环。不能保证在一次通话中转移全部金额。

09-10 08:33