2016-10-14 13 views
0

Моя программа использует задачи JavaFX для загрузки и распаковки файлов и для отображения прогресса на экране с использованием метода updateProgress(workDone, max) и метода progressProperty().bind(observable). Он работает для скачивания:Java - Unzip и Progress Bar

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

} 

Но это не очень хорошо работает для разархивирует: Файл правильно распаковали, но я получаю неправильный ProgressBar (пусто в конце).

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

«Файл правильно распакованы, но я получаю неправильный ProgressBar (пусто в конце).» Таким образом, это происходит примерно с 100% до 0%? Разве это не должно быть? Это вывод на консоль, который вы отправили, цифры подсчитываются, а не вверх, вызывается 'updateProgress (nread, length)', где 'nread' подсчитывается. Кроме того, похоже, что 'nread' идет вверх и вниз, потому что вы обрабатываете несколько записей, поэтому я ожидаю, что ваш индикатор прогресса будет идти вверх и вниз, возможно, слишком быстро, чтобы увидеть ... – DavidS

+0

@DavidS Да, это слишком быстро, я не вижу, как это меняется. Я пытаюсь что-то замедлить прогресс. EDIT: Похоже, он растет, но он несколько раз сбрасывается. – Franckyi

+0

Я вижу, что вы правы, он растет, но несколько раз перезагружается. Ответ James_D, вероятно, исправит. – DavidS

ответ

1

Это связано с тем, что вы используете длину сжатого zipFile как максимум, а количество байтов, полученных из каждого несжатого zipEntry, в качестве публикации - размер сжатого файла в большинстве случаев отличается от несжатого, также вы можете несколько файлов в zip-пакете - поэтому прогрессы будут переходить от 0 до некоторого значения (размер фактического zipEntry, а не сжатая длина zipFile) для каждого в этом случае. Для того, чтобы иметь реальное положение в почтовый файл, получить ссылку на FileChannel из FileInputStream, используя этот метод: FileInputStream#getChannel();

тогда, когда речь идет обновлять Progres сделать:

updateProgress(channel.position(), length); 

Это обновит прогресс bar в соответствии с фактическим положением, которое было записано в 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

Добро пожаловать :) –