الحصول على حجم البيانات غير المضغوطة في زليب؟

StackOverflow https://stackoverflow.com/questions/929757

سؤال

أقوم بإنشاء شيء يتضمن خدمة تحميل ملفات من نوع ما، وأحتاج إلى تخزين البيانات المضغوطة مع دالة ضغط ZLIB (). أرسلها عبر الإنترنت مضغوط بالفعل، لكنني بحاجة إلى معرفة حجم الملف غير المضغوط على الخادم البعيد. هل هناك أي طريقة يمكنني معرفة هذه المعلومات دون عدم الضغط على البيانات () جي البيانات الموجودة على الخادم أولا، فقط للكفاءة؟ هذه هي الطريقة التي أفعلها الآن، ولكن إذا كان هناك اختصار أحب أن أعتبره.

بالمناسبة، لماذا يطلق عليه عدم الضغط؟ هذا يبدو فظيعا بالنسبة لي، اعتقدت دائما أنه سيكون إلغاء ضغط ...

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

المحلول

لا يحتوي تنسيق ZLIB على حقل لحجم الإدخال الأصلي، لذلك أشك في أنك ستكون قادرا على القيام بذلك دون محاكاة الضغط من البيانات. ال شكل gzip لديه "حجم الإدخال" (ISIZE) الحقل، أنه يمكنك استخدامه، ولكن ربما تريد تجنب تغيير تنسيق الضغط أو امتلاك العملاء الذين يرسلون حجم الملف.

ولكن حتى إذا كنت تستخدم تنسيقا مختلفا، إذا كنت لا تثق بالعملاء، فستظل بحاجة إلى إجراء فحص أكثر تكلفة للتأكد من أن البيانات غير المضغوطة هي الحجم الذي يقوله العميل إنه كذلك. في هذه الحالة، ما يمكنك القيام به هو جعل إلغاء ضغط - / dev / null عملية أقل تكلفة، والتأكد من عدم كتابة ZLIB بيانات الإخراج في أي مكان، كما تريد فقط معرفة الحجم غير المضغوط.

نصائح أخرى

أنا أشك في ذلك. لا أعتقد أن هذا شيء يوفر مكتبات Zlib الأساسية من الذاكرة (على الرغم من أنها كانت جيدة 7 أو 8 سنوات منذ أن استخدمتها، لا يبدو أن المستندات الحديثة تشير إلى أنه تمت إضافة هذه الميزة).

يمكن أن يكون أحد الاحتمالات نقل ملف آخر يحتوي على الحجم غير المضغوط (على سبيل المثال، نقل كليهما file.zip و file.zip.size) ولكن يبدو ذلك محفوفا بالخطر، خاصة إذا حصلت على حجم الخطأ.

بديل آخر هو، إذا كان الخادم غير مضغوط هو الوقت المناسب ولكن لا يجب القيام به على الفور، للقيام بذلك في مهمة خلفية ذات أولوية أقل (مثل مع nice تحت لينكس). ولكن مرة أخرى، قد يكون هناك عيوب إذا كان المدقق حجم يبدأ قيد التشغيل (العديد من عمليات التحميلات القادمة).

وأنا أميل إلى التفكير في تخفيف الضغط من حيث "الضغط المتفجر"، وليس مصطلحا جيدا لاستخدامه :-)

إذا كنت تقوم بالتحميل باستخدام تنسيق "ضغط" RAW، فلن تتمكن من الحصول على معلومات حول حجم البيانات التي يتم تحميلها. PAX صحيحة في هذا الصدد.
يمكنك تخزينه كأحد رأس 4 بايت في بداية المخزن المؤقت ضغط - على افتراض أن حجم الملف لا يتجاوز 4GB.
بعض رمز C كمثال:

 uint8_t *compressBuffer = calloc(bufsize + sizeof (uLongf), 0);
 uLongf compressedSize = bufsize;
 *((uLongf *)compressBuffer) = filesize;
 compress(compressBuffer + sizeof (uLongf), &compressedSize, sourceBuffer, bufsize);

ثم ترسل الضغوط الكاملة من الحجم المضغوط + Sizeof (ULONGF). عند استلامها على جانب الخادم، يمكنك استخدام التعليمات البرمجية التالية للحصول على البيانات مرة أخرى:

 // data is in compressBuffer, assume you already know compressed size.
 uLongf originalSize = *((uLongf *)compressBuffer);
 uint8_t *realCompressBuffer = compressBuffer + sizeof (uLongf);

إذا كنت لا تثق في العميل لإرسال الحجم الصحيح، فستحتاج إلى إجراء نوع من البيانات غير المضغوطة على حجم الخادم. اقتراح استخدام Unfress to / dev / null هو واحد معقول.
إذا كنت تقوم بتحميل ملف .zip، فهو يحتوي على دليل يخبرك بحجم الملف عندما يكون غير مضغوط. تم تصميم هذه المعلومات في تنسيق الملف، مرة أخرى، على الرغم من أن هذا يخضع للعملاء الضارين.

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