Как накачать файл с помощью zlib.NET? - PullRequest
4 голосов
/ 09 октября 2008

Я использую библиотеку zlib.NET , чтобы попытаться накачать файлы, сжатые zlib (возможно, на Linux-коробке) Вот что я делаю:

zlib.ZInputStream zinput =
    new zlib.ZInputStream(File.Open(path, FileMode.Open, FileAccess.Read));

while (stopByte != (data = zinput.ReadByte()))
{
  // check data here
}

zinput.Close();

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

Ответы [ 6 ]

7 голосов
/ 09 октября 2008

Кажется, я допустил ошибку, предполагая, что все виртуальные методы были переопределены, что не имело место. Я использовал zlib.ZInputStream.ReadByte (), который является просто унаследованным Stream.ReadByte (), который не выполняет раздувание.

Вместо этого я использовал zlib.ZInputStream.Read (), и он работал как надо.

7 голосов
/ 09 октября 2008

Кроме того, что я не могу использовать оператор using для закрытия потока даже в случае исключения, это выглядит хорошо для меня. Данные определенно сжаты? Вы можете распаковать его с помощью zlib на linux box?

Посмотрев на исходный код, он выглядит довольно ужасно - например, вызов int Read(buffer, offset, length) в итоге вызовет его внутренний int Read() метод length раз. Учитывая такое шаткое начало, я не уверен, что буду особенно сильно доверять коду, но я ожидал бы, что он будет работать по крайней мере немного ! Вы пробовали использовать SharpZipLib ?

3 голосов
/ 22 ноября 2015

Пропуск заголовка zlib (первые два байта, 78 9C), а затем использование DeflateStream, встроенного в .net, помогли мне.

using(var input = File.OpenRead(...))
using(var output = File.Create(...))
{
    // if there are additional headers before the zlib header, you can skip them:
    // input.Seek(xxx, SeekOrigin.Current);

    if (input.ReadByte() != 0x78 || input.ReadByte() != 0x9C)//zlib header
        throw new Exception("Incorrect zlib header");

    using (var deflateStream = new DeflateStream(decryptedData, CompressionMode.Decompress, true))
    {
        deflateStream.CopyTo(output);
    }
}
2 голосов
/ 23 января 2009

Код ниже может помочь вам, ребята. Создайте объект и используйте функции.

public class FileCompressionUtility
{
    public FileCompressionUtility()
    {
    }

    public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }

    public void compressFile(string inFile, string outFile)
    {
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION);
        System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
        try
        {
            CopyStream(inFileStream, outZStream);
        }
        finally
        {
            outZStream.Close();
            outFileStream.Close();
            inFileStream.Close();
        }
    }

    public void uncompressFile(string inFile, string outFile)
    {
        int data = 0;
        int stopByte = -1;
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZInputStream inZStream = new zlib.ZInputStream(System.IO.File.Open(inFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
        while (stopByte != (data = inZStream.Read()))
        {
            byte _dataByte = (byte)data;
            outFileStream.WriteByte(_dataByte);
        }

        inZStream.Close();
        outFileStream.Close();
    }
}
0 голосов
/ 12 марта 2013

У меня недавно была неудача в предоставлении документов, ранее zlib'd с использованием php для различных браузеров и платформ, включая IE7. Как только я понял, что документы были zlib'd, а не gzip'd (как думали в то время), я использовал SharpZipLib следующим образом в .NET Framework v4 (используя преимущества Stream .CopyTo ):

public static byte[] DecompressZlib(Stream source)
{
    byte[] result = null;
    using (MemoryStream outStream = new MemoryStream())
    {
        using (InflaterInputStream inf = new InflaterInputStream(source))
        {
            inf.CopyTo(outStream);
        }
        result = outStream.ToArray();
    }
    return result;
}

Думаю, я бы поставил это здесь на тот случай, если кому-то понадобится помощь в использовании классов из SharpZipLib.

0 голосов
/ 09 октября 2008

Посмотрите на пример кода более внимательно, он копирует данные из обычного Filestream в ZOutputStream. Декомпрессия должна происходить через этот слой.

private void decompressFile(string inFile, string outFile)
{
    System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
    zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
    System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);          
    try
    {
        CopyStream(inFileStream, outZStream);
    }
    finally
    {
        outZStream.Close();
        outFileStream.Close();
        inFileStream.Close();
    }
}
...