Question

Aimez ce site! Mon problème est le suivant:

Je suis en train de lire un fichier zip venant d'un HTTP "PUT". demande. L'en-tête de la demande m'indique que la longueur du contenu est (par exemple) de 1 Mo. Le code suivant crée le ZipInputStream et enregistre le contenu du zip dans les fichiers du répertoire en cours:

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();

Quand tout est dit et fait, totalBytesRead est égal à environ 1,5 Mo (en fonction de la compression des fichiers, cela pourrait être n'importe quoi!). Ce que j'aimerais savoir, c'est s'il existe un moyen de savoir combien d'octets réels ont été lus dans le inputStream d'origine? ze.getSize () et ze.getCompressedSize () renvoient -1 pour chaque entrée compressée (c'est-à-dire qu'elle ne le sait pas). J'ai besoin de cette information pour une barre de progression indiquant combien d'octets du fichier zip transmis ont été lus sur le réseau.

Des suggestions? Dois-je peut-être sous-classer ZipInputStream et essayer de savoir combien d'octets sont lus à partir de son entrée InputStream?

Merci d'avance!

Était-ce utile?

La solution

Bien sûr, cela semble raisonnable.

Il existe essentiellement deux options: lire tous les octets, les stocker (en mémoire ou dans un fichier), les compter, puis les décompresser; ou les compter comme ils entrent. Le premier semble inefficace, et le dernier nécessitera une sous-classe de InputStream qui a la capacité de compter les octets lus. Je n'arrive pas à en trouver un dans la bibliothèque standard, mais des implémentations existent probablement. Il serait alors assez facile d'écrire la vôtre.

Autres conseils

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

}

Cela se situe entre, comme

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

Merci à vous deux! Je viens de finir de faire à peu près exactement ce que Clint a suggéré!

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

Maintenant, je me demande qui je devrais donner le petit "check-mark". à ...?

Merci encore!

C’est ce que je fais ... plus besoin de remplacer quoi que ce soit.

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();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top