2012-08-25 13 views
5

Pobieram niektóre pliki w mojej aplikacji java i zaimplementowałem okno dialogowe monitora pobierania. Ale ostatnio skompresowałem wszystkie pliki za pomocą gzip, a teraz monitor pobierania jest trochę uszkodzony.Monitor GZip Pobierz Postęp w Javie

Otwieram plik jako GZIPInputStream i aktualizuję status pobierania po każdym pobraniu kB. Jeśli plik ma rozmiar 1 MB, postępy idą do np. 4 MB, czyli rozmiar nieskompresowany. Chcę monitorować skompresowany postęp pobierania. czy to możliwe?

EDYCJA: Aby wyjaśnić: Czytam bajty z GZipInputStream, które są nieskompresowane bajty. To nie daje mi odpowiedniego rozmiaru na końcu.

Oto mój kod:

URL url = new URL(urlString); 
HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
con.connect(); 
... 
File file = new File("bibles/" + name + ".xml"); 
if(!file.exists()) 
    file.createNewFile(); 
out = new FileOutputStream(file); 
in = new BufferedInputStream(new GZIPInputStream(con.getInputStream())); 

byte[] buffer = new byte[1024]; 
int count; 
while((count = in.read(buffer)) != -1) { 
    out.write(buffer, 0, count); 
    downloaded += count; 
    this.stateChanged(); 
} 

... 

private void stateChanged() { 
    this.setChanged(); 
    this.notifyObservers(); 
} 

Dzięki za wszelką pomoc!

+0

Czytam bajty pobrane przez 'GZipInputStream', który jest nieskompresowanym strumieniem. To nie jest prawdziwy plik, który jest pobierany. – dbrettschneider

+0

Ok, teraz to widzę. – SJuan76

Odpowiedz

4

Zgodnie ze specyfikacją, GZIPInputStream jest podklasą InflaterInputStream. InflaterInputStream ma pole protected Inflater inf, które jest Inflater używane do pracy dekompresji. Inflater.getBytesRead powinien być szczególnie przydatny do twoich celów.

Niestety, GZIPInputStream nie wystawia inf, więc prawdopodobnie będziesz musiał stworzyć własną podklasę i ujawnić Inflater, np.

public final class ExposedGZIPInputStream extends GZIPInputStream { 

    public ExposedGZIPInputStream(final InputStream stream) { 
    super(stream); 
    } 

    public ExposedGZIPInputStream(final InputStream stream, final int n) { 
    super(stream, n); 
    } 

    public Inflater inflater() { 
    return super.inf; 
    } 
} 
... 
final ExposedGZIPInputStream gzip = new ExposedGZIPInputStream(...); 
... 
final Inflater inflater = gzip.inflater(); 
final long read = inflater.getBytesRead(); 
+0

Dzięki! Musiałem zaimplementować niestandardowy GZIPInputStream, który udostępnia 'getBytesRead()' z 'Inflater int'. – dbrettschneider

+0

Dzięki, właśnie tego szukałem! –