Domanda

Ho usato il codice qui sotto per comprimere i file e continuano a crescere invece di ridursi. Ho compresso un file di 4 KB ed è diventato 6. Questo è comprensibile per un piccolo file a causa del sovraccarico di compressione. Ho provato un file da 400 mb e dopo la compressione è diventato 628 mb. Che c'è? Vedi il codice (.net 2.0)

Public Sub Compress(ByVal infile As String, ByVal outfile As String)
    Dim sourceFile As FileStream = File.OpenRead(inFile)
    Dim destFile As FileStream = File.Create(outfile)

    Dim compStream As New GZipStream(destFile, CompressionMode.Compress)

    Dim myByte As Integer = sourceFile.ReadByte()
    While myByte <> -1
        compStream.WriteByte(CType(myByte, Byte))
        myByte = sourceFile.ReadByte()
    End While

    sourceFile.Close()
    destFile.Close()
End Sub
È stato utile?

Soluzione

Sei sicuro che scrivere byte per byte nello stream sia davvero una buona idea? Non avrà certamente caratteristiche prestazionali ideali e forse è questo che confonde anche l'algoritmo di compressione gzip.

Inoltre, potrebbe accadere che i dati che si sta tentando di comprimere non siano realmente ben comprimibili. Se fossi in te, proverei il tuo codice con un documento di testo della stessa dimensione dei documenti di testo che tendono a comprimersi molto meglio del binario casuale.

Inoltre, potresti provare a utilizzare un DeflateStream puro invece di un GZipStream in quanto entrambi utilizzano lo stesso algoritmo di compressione (deflate), l'unica differenza è che gzip aggiunge alcuni dati aggiuntivi (come il controllo degli errori) in modo che un DeflateStream possa produrre più piccoli risultati.

Il mio VB.NET è un po 'arrugginito, quindi preferisco non provare a scrivere un esempio di codice in VB.NET. Invece, ecco come dovresti farlo in C #, dovrebbe essere relativamente semplice tradurlo in VB.NET per qualcuno con un po 'di esperienza: (o forse qualcuno che è bravo in VB.NET potrebbe modificare il mio post e tradurlo in VB.NET)

FileStream sourceFile;
GZipStream compStream;

byte[] buffer = new byte[65536];
int bytesRead = 0;
while (bytesRead = sourceFile.Read(buffer, 0, 65536) > 0)
{
     compStream.Write(buffer, 0, bytesRead);
}

Altri suggerimenti

Se il file sottostante è di per sé altamente imprevedibile (già compresso o in gran parte casuale), il tentativo di comprimerlo farà sì che il file diventi più grande.

Passare da 400 a 628 Mb sembra altamente improbabile come fattore di espansione poiché l'algoritmo di deflazione (usato per GZip) tende verso un fattore di espansione massimo dello 0,03% Il sovraccarico dell'intestazione GZip dovrebbe essere trascurabile.

Modifica: la versione 4.0 di c # indica che le librerie di compressione sono state migliorate per non causare un'espansione significativa di dati non comprimibili. Ciò suggerisce che non stavano implementando il & Quot; fallback ai blocchi di flusso grezzi & Quot; modalità. Prova a utilizzare la libreria di SharpZipLib come test rapido. Ciò dovrebbe fornire prestazioni quasi identiche quando lo stream è incomprimibile tramite deflate. Se considera la possibilità di passare a questo o di attendere la versione 4.0 per un'implementazione BCL più performante. Nota che la mancanza di compressione che stai ricevendo suggerisce fortemente che non ha senso tentare di comprimere ulteriormente

Questa è una anomalia nota con built- in GZipStream (e DeflateStream).
Mi vengono in mente due soluzioni alternative:

  • usa un compressore alternativo.
  • crea alcune logiche che esaminano la dimensione del " compresso " output e lo confronta con la dimensione dell'input. Se più grande, getta l'output e archivia semplicemente i dati.

DotNetZip include un " fisso " GZipStream basato su una porta gestita di zlib. (Prende l'approccio n. 1 dall'alto). Ionic.Zlib.GZipStream può sostituire GZipStream integrato nelle tue app con un semplice scambio di spazio dei nomi.

Grazie a tutti per le buone risposte. In precedenza ho provato a comprimere i file .wmv e un file di testo. Ho cambiato il codice in DeflateStream e sembra funzionare ora. Cin cin.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top