سؤال

أنا أستخدم 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();

تتطابق بايت البيانات مع بايت البيانات المضغوطة ، لذلك يجب أن أفعل شيئًا خاطئًا.

هل كانت مفيدة؟

المحلول 2

يبدو أنني ارتكبت خطأ في افتراض أن جميع الأساليب الافتراضية تم تجاوزها ، وهو ما لم يكن كذلك. كنت أستخدم zlib.zinputstream.readbyte () ، وهو مجرد تيار موروث. readbyte () ، والذي لا يفعل أي تضخيم.

لقد استخدمت zlib.zinputstream.read () بدلاً من ذلك ، وقد عملت كما ينبغي.

نصائح أخرى

بخلاف عدم استخدام عبارة "استخدام" لإغلاق الدفق حتى في مواجهة الاستثناء ، يبدو ذلك جيدًا بالنسبة لي. هل البيانات مضغوطة بالتأكيد؟ هل يمكنك إلغاء ضغطه باستخدام Zlib على صندوق Linux؟

بعد أن نظرت إلى الكود المصدر ، إنه مروع للغاية - دعوة إلى int Read(buffer, offset, length) سينتهي به المطاف استدعاءه الداخلي int Read() طريقة length مرات على سبيل المثال. بالنظر إلى هذا النوع من البداية المهزوزة ، لست متأكدًا من أنني أثق في الرمز بشكل خاص ، لكنني كنت أتوقع أن يعمل على الأقل بعض الشيء! هل حاولت استخدام Sharpziplib?

تخطي رأس 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);
    }
}

يمكن أن يساعدك الرمز أدناه يا رفاق. مثيل للكائن واستفد من الوظائف.

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

انظر إلى رمز العينة عن كثب ، فهو يقوم بنسخ البيانات من 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();
    }
}

لقد حصلت مؤخرًا على سوء الحظ في تقديم مستندات سابقًا 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top