我正在编写一个从特定站点下载mp3列表的刮板(1,700多个mp3,每个15 MB)。给我的方法一个URL的List
和一个目标文件夹。
我想围绕它编写一个JProgressBar
对话框,该对话框具有:
当前的传输速率。
当前正在下载的文件信息(完成了多少/剩余了多少)。
我使用的是转移到ReadableByteChannel
的FileOutputStream
(或更准确地说,是从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().
一个电话是不够的。你必须循环。不能保证在一次通话中转移全部金额。