Frage

Liebe diese Website! Mein Problem ist wie folgt:

Ich bin eine Zip-Datei zu lesen, die von einem HTTP über ein Netzwerk kommen „PUT“ Anfrage. Der Request-Header sagt mir, dass die Content-Length ist (sagen wir) 1 MB. Der folgende Code erstellt die ZipInputStream und speichert den zip Inhalt von Dateien im aktuellen Verzeichnis:

ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze;
long totalBytesRead = 0;
while ((ze = zis.getNextEntry()) != null) {
    BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(ze.getName()));
    byte[] buffer = new byte[4096];
    int i;
    while ((i = zis.read(buffer)) != -1) {
        totalBytesRead+=i;
        outStream.write(buffer,0,i);
    } 
    outStream.close();
}
inputStream.close();

Wenn alles gesagt und getan ist, totalBytesRead auf etwa 1,5 MB gleich ist (abhängig von der Komprimierung der Dateien, könnte alles obwohl sein!). Was Ich mag würde, wissen, ob es einen Weg, wie viele tatsächliche Bytes, um herauszufinden, ist haben von der ursprünglichen inputStream gelesen? Sowohl ze.getSize() und ze.getCompressedSize() return -1 für jeden Reißverschluss Eintrag (das heißt es nicht weiß). Ich brauche diese Informationen für einen Fortschrittsbalken, wie viele Bytes der gesendeten Zip-Datei zu zeigen, haben das Netzwerk abgelesen wurde.

Verbesserungsvorschläge? Soll ich vielleicht eine Unterklasse ZipInputStream und versuchen, herauszufinden, wie viele Bytes es liest aus es gewickelt Input?

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Sicher, das scheint vernünftig.

Es gibt grundsätzlich zwei Möglichkeiten: alle Bytes lesen, speichern Sie sie (im Speicher oder einer Datei), zählen sie, dann dekomprimieren; oder zählen sie, wie sie hereinkommen. Die ehemalige ineffizient scheint, und dieser wird eine Unterklasse von InputStream erfordern, die die Fähigkeit hat, das Bytes zu zählen es liest. Ich kann nicht glauben, von einem in der Standard-Bibliothek, aber Implementierungen existieren wahrscheinlich draußen -. Dann wieder würde es ziemlich einfach sein, Ihre eigenen schreiben

Andere Tipps

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 
 */

/**
 * @author clint
 * 
 */
public class ByteCountingInputStream extends FilterInputStream {

  public int totalRead = 0;

  /**
   * @param in
   */
  protected ByteCountingInputStream(InputStream in) {
    super(in);
    // TODO Auto-generated constructor stub
  }

  /* (non-Javadoc)
   * @see java.io.FilterInputStream#read()
   */
  @Override
  public int read() throws IOException {
    int ret = super.read();
    totalRead++;
    return ret;
  }

  /* (non-Javadoc)
   * @see java.io.FilterInputStream#read(byte[], int, int)
   */
  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    int ret = super.read(b, off, len);
    totalRead += ret;
    return ret;
  }

  /* (non-Javadoc)
   * @see java.io.FilterInputStream#read(byte[])
   */
  @Override
  public int read(byte[] b) throws IOException {
    int ret = super.read(b);
    totalRead += ret;
    return ret;
  }

  /* (non-Javadoc)
   * @see java.io.FilterInputStream#skip(long)
   */
  @Override
  public long skip(long n) throws IOException {
    //What to do?
    return super.skip(n);
  }

  /**
   * @return the totalRead
   */
  protected int getTotalRead() {
    return this.totalRead;
  }

}

Das geht dazwischen wie

ZipInputStream zis = new ZipInputStream(new ByteCountingInputStream(inputStream));

Danke euch beiden! Ich habe gerade ziemlich genau das machen, was Clint! Vorgeschlagen

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class CountingInputStream extends FilterInputStream {

    private long totalBytes = 0;

    protected CountingInputStream(InputStream in) {
        super(in);
    }

    public int getTotalBytesRead() {
        return totalBytes;
    }

    @Override
    public int read() throws IOException {
        int byteValue = super.read();
        if (byteValue != -1) totalBytes++;
        return byteValue;
    }

    @Override
    public int read(byte[] b) throws IOException {
        int bytesRead = super.read(b);
        if (bytesRead != -1) totalBytes+=bytesRead;
        return bytesRead;
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int bytesRead = super.read(b,off,len);
        if (bytesRead != -1) totalBytes+=bytesRead;
        return bytesRead;
    }
}

Jetzt frage ich mich, wen ich soll die kleine geben "Check-mark" zu ...?

Danke nochmal!

Das ist, was ich tue ... keine Notwendigkeit, etwas zu überschreiben.

ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze;
int totalBytes = inputStream.available();
int totalBytesRead = 0;
while ((ze = zis.getNextEntry()) != null) {
    totalBytesRead = totalBytes - inputStream.available();
    BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(ze.getName()));
    byte[] buffer = new byte[4096];
    int i;
    while ((i = zis.read(buffer)) != -1) {
        outStream.write(buffer,0,i);
    } 
    outStream.close();
}
inputStream.close();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top