【发布时间】:2018-01-23 22:04:43
【问题描述】:
我正在尝试从给定的 url 下载 .zip 存档并将其解压缩到选定的位置。由于下载量很大,我尝试在不同的线程中执行它,因此它不会冻结整个事情,但它并没有真正取得完全成功......通常,我会创建一个可运行和线程对象,但现在,由于我使用的是 javafx,它给出了一些错误。我在网上搜索,我不得不改用Platform.runLater()。这是我的代码:
private void startTask(Label st, ListView<String> view, HashMap<String, String> hash)
{
Platform.runLater(new Runnable() {
@Override
public void run() {
runTask(st,view,hash);
}
});
}
private void runTask(Label st, ListView<String> view, HashMap<String, String> hash){
String link = hash.get(view.getSelectionModel().getSelectedItem());
File file = new File("temp.zip");
try {
FileUtils.copyURLToFile(new URL(link), file);
byte[] buffer = new byte[1024];
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry zipEntry = zis.getNextEntry();
File newFile;
FileOutputStream fos;
String fileName;
while(zipEntry != null){
fileName = zipEntry.getName();
if(fileName.contains("##TEMP##")) continue;
if(fileName.contains("MACOSX")) continue;
newFile = new File(fileName);
fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
st.setText("Status: Ready");
}
结果如下:39ko temp.zip 文件似乎已损坏。它不会解压缩(显然)。我尝试了来自多个域的许多链接,仍然是同样的问题...
编辑:尝试了不同的方法...同样的错误..新代码:
URL url = new URL(link);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream in = connection.getInputStream();
FileOutputStream out = new FileOutputStream("download.zip");
copy(in, out, 1024);
out.close();
public static void copy(InputStream input, OutputStream output, int bufferSize) throws IOException {
byte[] buf = new byte[bufferSize];
int n = input.read(buf);
while (n >= 0) {
output.write(buf, 0, n);
n = input.read(buf);
}
output.flush();
}
我评论了解压部分,还是一样...结论:下载是问题。
【问题讨论】:
-
是什么让您认为这个问题与 JavaFX 有关系?如果在控制台应用程序中运行,完全相同的代码是否有效?
-
我并不是说它与 javafx 有任何关系...我说我必须使用
Platform.runLater()所以没有人问我为什么这样做。它很可能在控制台中做同样的事情。 -
你在 while 循环的顶部做一个 if(fileName.contains()) 检查,它可以继续,但是 zipEntry = zis.getNextEntry();位于循环的底部,因此不会调用 zis.getNextEntry()。它是否陷入了无限循环?
-
您遇到的另一个问题是其中两个线程无法同时执行,因为固定文件名
test.zip。你需要让它动态化。如果您不需要实际的 .zip 文件,直接从 URL 连接的输入流中解压缩会更有效。 -
附注:不要在
runLater()任务中下载和解压缩文件。在后台线程中执行此操作。只有在下载并解压缩文件后,该任务才应调用runLater()来更新 UI。 JavaFX 应用程序线程是处理所有 GUI 事件的地方。使用它来执行网络 IO 和其他不可靠、可能持续时间较长的任务会使 UI 无响应。
标签: java multithreading javafx download