Вопрос по c#, decompression, gzipstream, compression – GZipStream и декомпрессия

11

У меня есть код, который должен сделать сжатие:

FileStream fs = new FileStream("g:\\gj.txt", FileMode.Open);
FileStream fd = new FileStream("g:\\gj.zip", FileMode.Create);
GZipStream csStream = new GZipStream(fd, CompressionMode.Compress);

byte[] compressedBuffer = new byte[500];
int offset = 0;
int nRead;

nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
while (nRead > 0)
{
    csStream.Write(compressedBuffer, offset, nRead);
    offset = offset + nRead;
    nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
}

fd.Close();
fs.Close();

и я думаю, что это так, но я хочу распаковать то, что было сжато выше. Я делаю что-то подобное:

FileStream fd = new FileStream("g:\\gj.new", FileMode.Create);
FileStream fs = new FileStream("g:\\gj.zip", FileMode.Open);
GZipStream csStream = new GZipStream(fs, CompressionMode.Decompress);

byte[] decompressedBuffer = new byte[500];
int offset = 0;
int nRead;

nRead=csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
while (nRead > 0)
{
    fd.Write(decompressedBuffer, offset, nRead);
    offset = offset + nRead;
    nRead = csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
}

fd.Close();
fs.Close();

и здесь это не ... У меня есть nRead = 0, прежде чем войти в цикл ... Что я делаю не так ?? Тестовый файл, который я использую, является самым простым TEXT-файлом (размер: 104 байта) ...

Отредактированный ответ, чтобы показать и читать, и писать Marc Gravell♦
Обратите внимание, что gzip! = ".Zip" Marc Gravell♦
(обратите внимание, я исправил ошибку после публикации; проверьте, что обаwhile только петлиRead в верхней строке (не в нижней части). Marc Gravell♦

Ваш Ответ

3   ответа
16

csStream, Если вы используетеusing это происходит автоматически. Так как gzip буферизует данные, вы можете пропустить некоторые из них.

Во-вторых, не увеличиватьoffset; это смещение вбуфер (не поток). Оставьте в 0:

using (Stream fs = File.OpenRead("gj.txt"))
using (Stream fd = File.Create("gj.zip"))
using (Stream csStream = new GZipStream(fd, CompressionMode.Compress))
{
    byte[] buffer = new byte[1024];
    int nRead;
    while ((nRead = fs.Read(buffer, 0, buffer.Length))> 0)
    {
        csStream.Write(buffer, 0, nRead);
    }
}

using (Stream fd = File.Create("gj.new.txt"))
using (Stream fs = File.OpenRead("gj.zip"))
using (Stream csStream = new GZipStream(fs, CompressionMode.Decompress))
{
    byte[] buffer = new byte[1024];
    int nRead;
    while ((nRead = csStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        fd.Write(buffer, 0, nRead);
    }
}
Хороший вопрос, просто добавив к этому немного знаний. Еще одна досадная вещь, которую я нашел с GZipStream. Если вы пишете в MemoryStream, вы должны .Close () GZipStream. В противном случае он будет держаться до последних нескольких байтов. .Flush (), похоже, не выполняет эту работу. (Это если вы используете MemoryStream внутри оператора using.) James Roland
@JamesR - нет, когда этот ответ был написан, я не мог; p Marc Gravell♦
Вместо буферного цикла вы также можете использовать встроенную функцию .CopyTo (). В этом случае это будет: csStream.CopyTo (fd); James Roland
Проблема в том, что сжатие работает хорошо, но не может его распаковать. user191612
Оно работает!!! Спасибо! user191612
-1

которые у меня есть, похожи на упомянутые Джеймс Роланд.

private static byte[] Compress(HttpPostedFileBase file)
{
    var to = new MemoryStream();
    var from = new GZipStream(to, CompressionMode.Compress);
    file.InputStream.CopyTo(from);
    from.Close();
    return to.ToArray();
}

private byte[] Decompress(byte [] img)
{
    var to = new MemoryStream();
    var from = new MemoryStream(img);
    var compress = new GZipStream(from, CompressionMode.Decompress);
    compress.CopyTo(to);
    from.Close();
    return to.ToArray();
}

Тем не менее, я использую загрузку с

Request.Files[0] 

затем сожмите и сохраните в БД. Затем я вытаскиваю IMG, распаковываю и устанавливаю SRC с

$"data:image/gif;base64,{ToBase64String(Decompress(img))}";
@ JCKödel Хотя он явно предпочел воспользоватьсяusing когда это возможно, говорить «никогда» просто не правильно, и есть множество обстоятельств, когда это нежелательно и / или возможно. ForeverZer0
Никогда не используйтеIDisposable объект безusing! JCKödel
0

using System;
using System.IO;
using System.IO.Compression;

// ...
    static void Main(string[] args)
    {
        string folder = @"c:\temp";
        string dataPath = Path.Combine(folder, "data.dat");
        string compressedPath = Path.Combine(folder, "compressed.gz");
        string decompressedPath = Path.Combine(folder, "decompressed.dat");

        using (FileStream fileReader = File.OpenRead(dataPath))
        using (FileStream fileWriter = File.Create(compressedPath))
        using (GZipStream compressionStream = new GZipStream(fileWriter, CompressionMode.Compress))
        {
            // Compresses and writes byte array contents to file

            int readlength = 0;
            byte[] buffer = new byte[1024];

            do
            {
                readlength = fileReader.Read(buffer, 0, buffer.Length);
                compressionStream.Write(buffer, 0, readlength);

            } while (readlength > 0);
        }

        using (FileStream fileReader = File.OpenRead(compressedPath))
        using (FileStream fileWriter = File.OpenWrite(decompressedPath))
        using (GZipStream compressionStream = new GZipStream(fileReader, CompressionMode.Decompress))
        {
            // Decompresses and reads data from stream to file

            int readlength = 0;
            byte[] buffer = new byte[1024];

            do
            {
                readlength = compressionStream.Read(buffer, 0, buffer.Length);
                fileWriter.Write(buffer, 0, readlength);

            } while (readlength > 0);
        }

        FileInfo dataFile = new FileInfo(dataPath);
        FileInfo compressedFile = new FileInfo(compressedPath);
        FileInfo decompressedFile = new FileInfo(decompressedPath);
        Console.WriteLine($"Uncompressed file size: {dataFile.Length} bytes");
        Console.WriteLine($"Compressed file size: {compressedFile.Length} bytes");
        Console.WriteLine($"Decompressed file size: {decompressedFile.Length} bytes");

        Console.Write("Press any key to quit . . . ");
        Console.ReadKey(true);
    }

Похожие вопросы