2016-10-14 29 views
0

我的程序使用JavaFX的任务来下载和解压缩文件,并使用updateProgress(workDone, max)方法和progressProperty().bind(observable)方法在屏幕上显示进度。 它适用于下载:Java - 解压缩和进度条

package com.franckyi.lan.installer; 

import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import java.nio.file.Files; 
import java.nio.file.Paths; 

import javafx.concurrent.Task; 

public class DownloadTask extends Task<Void> { 

    private String file; 
    private String url; 

    public DownloadTask(String dir, String fileurl) { 
     file = dir; 
     url = fileurl; 
    } 

    @Override 
    protected Void call() throws Exception { 
     URLConnection connection = new URL(url).openConnection(); 
     long fileLength = connection.getContentLengthLong(); 

     try (InputStream is = connection.getInputStream(); 
       OutputStream os = Files.newOutputStream(Paths.get(file))) { 

      long nread = 0L; 
      byte[] buf = new byte[1024]; 
      int n; 
      while ((n = is.read(buf)) > 0) { 
       os.write(buf, 0, n); 
       nread += n; 
       updateProgress(nread, fileLength); 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void succeeded(){ 
     System.out.println("Download succeeded"); 
    } 

} 

但它并不适用于解压缩工作良好:该文件是正确的解压,但我得到一个错误的进度条(空末)。

package com.franckyi.lan.installer; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 

import javafx.concurrent.Task; 

public class UnZipTask extends Task<Void>{ 

    private File zipfile; 
    private File folder; 

    public UnZipTask(File zipfile, File folder){ 
     this.zipfile = zipfile; 
     this.folder = folder; 
    } 

    @Override 
    protected Void call() throws Exception { 
     ZipInputStream zis = new ZipInputStream(
      new BufferedInputStream(new FileInputStream(zipfile.getCanonicalFile()))); 
     ZipEntry ze = null; 
     try { 
      while ((ze = zis.getNextEntry()) != null) { 
       File f = new File(folder.getCanonicalPath(), ze.getName()); 
       if (ze.isDirectory()) { 
        f.mkdirs(); 
        continue; 
       } 
       f.getParentFile().mkdirs(); 
       OutputStream fos = new BufferedOutputStream(new FileOutputStream(f)); 
       try { 
        try { 
         final byte[] buf = new byte[1024]; 
         int bytesRead; 
         long nread = 0L; 
         long length = zipfile.length(); 

         while (-1 != (bytesRead = zis.read(buf))){ 
          fos.write(buf, 0, bytesRead); 
          nread += bytesRead; 
          System.out.println(nread + "/" + length); 
          updateProgress(nread, length); 
         } 
        } finally { 
         fos.close(); 
        } 
       } catch (final IOException ioe) { 
        f.delete(); 
        throw ioe; 
       } 
      } 
     } finally { 
      zis.close(); 
     } 
     return null; 
    } 

    @Override 
    protected void succeeded(){ 
     System.out.println("Unzip succeeded"); 
    } 

} 

这是我在控制台中:

Download succeeded 
1024/91804 
2048/91804 
2815/91804 
362/91804 
326/91804 
290/91804 
386/91804 
257/91804 
250/91804 
588/91804 
1101/91804 
1613/91804 
2128/91804 
2646/91804 
3159/91804 
3672/91804 
4185/91804 
4701/91804 
5214/91804 
5731/91804 
6243/91804 
6755/91804 
7272/91804 
7793/91804 
8326/91804 
8862/91804 
9379/91804 
9897/91804 
10411/91804 
10927/91804 
11442/91804 
11956/91804 
12437/91804 
447/91804 
437/91804 
978/91804 
1525/91804 
2040/91804 
454/91804 
1056/91804 
1568/91804 
2089/91804 
2672/91804 
3198/91804 
3728/91804 
4282/91804 
4826/91804 
5377/91804 
5891/91804 
6413/91804 
6941/91804 
7480/91804 
8027/91804 
8565/91804 
9088/91804 
9609/91804 
9794/91804 
507/91804 
1019/91804 
1531/91804 
2043/91804 
2239/91804 
134/91804 
548/91804 
1292/91804 
2316/91804 
2584/91804 
507/91804 
837/91804 
135/91804 
486/91804 
1001/91804 
1514/91804 
2027/91804 
2545/91804 
3057/91804 
3571/91804 
4086/91804 
4599/91804 
5113/91804 
5627/91804 
6144/91804 
6655/91804 
7166/91804 
7679/91804 
8196/91804 
8710/91804 
9229/91804 
9745/91804 
10259/91804 
10773/91804 
11288/91804 
11802/91804 
12321/91804 
12834/91804 
13348/91804 
13864/91804 
14378/91804 
14893/91804 
15407/91804 
15918/91804 
16431/91804 
16944/91804 
17458/91804 
17971/91804 
18484/91804 
18997/91804 
19508/91804 
20021/91804 
20535/91804 
21047/91804 
21560/91804 
22072/91804 
22584/91804 
23096/91804 
23609/91804 
24122/91804 
24638/91804 
25149/91804 
25664/91804 
26176/91804 
26689/91804 
27203/91804 
27715/91804 
28227/91804 
28739/91804 
29251/91804 
29764/91804 
30277/91804 
30789/91804 
31301/91804 
31813/91804 
32325/91804 
32838/91804 
33306/91804 
33819/91804 
34333/91804 
34846/91804 
35357/91804 
35869/91804 
36381/91804 
36894/91804 
37407/91804 
37922/91804 
38435/91804 
38948/91804 
39460/91804 
39972/91804 
40488/91804 
41002/91804 
41514/91804 
42028/91804 
42540/91804 
43052/91804 
43566/91804 
44079/91804 
44594/91804 
45105/91804 
45619/91804 
46132/91804 
46644/91804 
47156/91804 
47668/91804 
48180/91804 
48692/91804 
49204/91804 
49716/91804 
50228/91804 
50741/91804 
51252/91804 
51765/91804 
52277/91804 
52790/91804 
53305/91804 
53821/91804 
54335/91804 
54852/91804 
55365/91804 
55881/91804 
56396/91804 
56442/91804 
545/91804 
1287/91804 
2311/91804 
2584/91804 
507/91804 
845/91804 
4/91804 
Unzip succeeded 

有人能帮助我吗?

+0

“的文件正确解压缩,但我得到一个错误的进度(末尾空)。”所以它从几乎100%下降到0%?它不应该这样做吗?它是你发布的控制台输出,数字正在倒计时,而不是起来,大大都在调用'updateProgress(nread,length)',其中'nread'正在倒计时。此外,它看起来像'nread'正在上升和下降,因为你正在处理多个条目,所以我希望你的进度条上下,可能太快,看不到... – DavidS

+0

@DavidS是的,这是太快了,我看不出它是如何变化的。我正在努力减慢进度。 编辑:它看起来像它正在上涨,但它重置几次。 – Franckyi

+0

我看你是对的,它正在上升,但几次重置。 James_D的回答可能会解决它。 – DavidS

回答

1

这是因为您使用压缩zipFile的长度作为最大值,并且从每个未压缩的zipEntry作为位置提取的字节数 - 压缩文件的大小在大多数情况下与未压缩的文件不同,也可以有zip包中的多个文件 - 所以在这种情况下,progres将从0跳到某个值(实际zipEntry的大小,而不是压缩的zipFile长度)。要在一个zip文件中的实际位置,您可以通过FileInputStream引用FileChannel,使用这种方法:FileInputStream#getChannel();

然后当它涉及到更新进步党做的事:

updateProgress(channel.position(), length); 

这将更新进度根据在zipFile中获得的实际位置(不是未压缩内容的大小)。

这可能是这样的:

package com.franckyi.lan.installer; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 

import javafx.concurrent.Task; 

public class UnZipTask extends Task<Void>{ 

    private File zipfile; 
    private File folder; 

    public UnZipTask(File zipfile, File folder){ 
     this.zipfile = zipfile; 
     this.folder = folder; 
    } 

    @Override 
    protected Void call() throws Exception { 
     FileInputStream is = new FileInputStream(zipfile.getCanonicalFile()); 
     FileChannel channel = is.getChannel(); 
     ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is)); 
     ZipEntry ze = null; 
     try { 
      while ((ze = zis.getNextEntry()) != null) { 
       File f = new File(folder.getCanonicalPath(), ze.getName()); 
       if (ze.isDirectory()) { 
        f.mkdirs(); 
        continue; 
       } 
       f.getParentFile().mkdirs(); 
       OutputStream fos = new BufferedOutputStream(new FileOutputStream(f)); 
       try { 
        try { 
         final byte[] buf = new byte[1024]; 
         int bytesRead; 
         long nread = 0L; 
         long length = zipfile.length(); 

         while (-1 != (bytesRead = zis.read(buf))){ 
          fos.write(buf, 0, bytesRead); 
          nread += bytesRead; 
          System.out.println(nread + "/" + length); 
          updateProgress(channel.position(), length); 
         } 
        } finally { 
         fos.close(); 
        } 
       } catch (final IOException ioe) { 
        f.delete(); 
        throw ioe; 
       } 
      } 
     } finally { 
      zis.close(); 
     } 
     return null; 
    } 

    @Override 
    protected void succeeded(){ 
     System.out.println("Unzip succeeded"); 
    } 

} 
+0

是的,谢谢你! – Franckyi

+0

不客气:) –