الوحدة Zlib في Node.js
مؤشر الاستقرار: 2 - مستقر
توفر الوحدة zlib
وظيفة الضغط باستخدام Gzip و Deflate/Inflate. ويمكن الوصول إليها باستخدام:
const zlib = require('zlib');
يمكن ضغط أو فك ضغط دفقٍ ما (مثل ملف) بتوجيه بيانات دفق المصدر من خلال دفق zlib
إلى دفق الوجهة:
const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');
inp.pipe(gzip).pipe(out);
من الممكن أيضا ضغط البيانات أو فك ضغطها في خطوة واحدة:
const input = '.................................';
zlib.deflate(input, (err, buffer) => {
if (!err) {
console.log(buffer.toString('base64'));
} else {
// معالجة الخطأ
}
});
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, (err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// معالجة الخطأ
}
});
استخدام مُجمّع الخيوط
لاحظ أن كافة واجهات برمجة تطبيقات zlib باستثناء تلك التي تكون متزامنة بشكل صريح تستخدم مُجمّع خيوط libuv. ويمكن أن يؤدي هذا إلى تأثيرات مفاجئة في بعض التطبيقات، مثل الأداء المتدني (والذي يمكن التخفيف منه عن طريق ضبط حجم المُجمّع) و/أو تقسيم الذاكرة غير القابل للاسترداد الكارثي.
ضغط طلبات واستجابات HTTP
يمكن استخدام الوحدة zlib
لتنفيذ دعم أليات ترميز المحتوي gzip
و deflate المُعرَّفة من قِبَل HTTP.
تستخدم ترويسة قبول الترميز Accept-Encoding
الخاصة HTTP ضمن طلب http لتعريف ترميزات الضغط المقبولة من قبل العميل. وتستخدم ترويسة ترميز المحتوي Content-Encoding
لتعريف ترميزات الضغط المُطبَّقة فعليًا علي رسالةٍ ما.
توضح الأمثلة التالية المفهوم الأساسي بشكل مبسط للغاية. يمكن أن يكون استخدام ترميز zlib
مُكلفًا، ويجب أن تُخزَّن النتائج مؤقتًا. راجع قسم ضبط استخدام الذاكرة للحصول على مزيد من المعلومات حول المفاضلات بين السرعة والذاكرة والضغط المتضمنين في استخدام zlib
.
// مثال على طلب العميل
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'example.com',
path: '/',
port: 80,
headers: { 'Accept-Encoding': 'gzip,deflate' } });
request.on('response', (response) => {
const output = fs.createWriteStream('example.com_index.html');
switch (response.headers['content-encoding']) {
// أو, استخدم فقط zlib.createUnzip() لمعالجة الحالتين
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output);
break;
default:
response.pipe(output);
break;
}
});
افتراضيًا، تُطلق توابع zlib
خطأً عند فك ضغط البيانات المبتورة. ومع ذلك، إذا كان من المعروف أن البيانات غير كاملة، أو كانت الرغبة في فحص بداية الملف المضغوط فقط، فمن الممكن منع معالجة الخطأ الافتراضي بواسطة تغيير تابع التدفق المستخدم لفك ضغط الجزء الأخير من البيانات المُدخَلة:
// هذه نسخة مبتورة من المخزن المؤقت من الأمثلة المذكورة أعلاه
const buffer = Buffer.from('eJzT0yMA', 'base64');
zlib.unzip(
buffer,
{ finishFlush: zlib.constants.Z_SYNC_FLUSH },
(err, buffer) => {
if (!err) {
console.log(buffer.toString());
} else {
// معالجة الخطأ
}
});
لن يؤدي ذلك إلى تغيير السلوك في حالات إطلاق الأخطاء الأخرى، علي سبيل المثال عندما يكون تنسيق البيانات المُدخَلة غير صالح. فباستخدام هذا التابع، لن يكون من الممكن تحديد ما إذا كان الإدخال قد انتهي قبل الأوان أم انه يفتقر إلى فحوص التكامل، مما يجعل من الضروري التحقق يدويًا من صحة النتيجة التي فُكَّ ضغطها.
ضبط استخدام الذاكرة
من zlib/zlib.h
، مُعدَّلة إلى استخدام Node js:
متطلبات الذاكرة للانكماش هي (بالبايت):
(1 << (windowBits + 2)) + (1 << (memLevel + 9))
أي: 128K لـ windowBits
= 15 + 128K لـ memLevel
= 8 (القيم الافتراضية) بالإضافة إلى عدد قليل من الكيلوبايت للكائنات الصغيرة.
علي سبيل المثال، لتقليل متطلبات الذاكرة الافتراضية من 256K إلى 128K، يجب ضبط الخيارات إلى:
const options = { windowBits: 14, memLevel: 7 };
ومع ذلك، سيؤدي هذا إلى انخفاض مقدار الضغط بشكل عام.
متطلبات الذاكرة للتضخيم هي (بالبايت) 1 << windowBits
. أي، 32K لـ windowBits
= 15 (القيمة الافتراضية) بالإضافة إلى عدد قليل من الكيلوبايت للكائنات الصغيرة.
هذا بالإضافة إلى شريحة المخزن المؤقت الوحيد للإخراج الداخلي والتي يكون حجمها chunkSize
، ذات القيمة الافتراضية 16K.
تتأثر سرعة ضغط zlib
بشكل كبير بإعداد المستوى. سيؤدي مستوي أعلي إلى ضغط أفضل، ولكن سيستغرق وقتًا أطول لإكماله. بينما سيؤدي مستوى أقل إلى ضغطٍ أقل، ولكن سيكون أسرع بكثير.
بشكل عام ستعني خيارات استخدام ذاكرة أكبر أن على Node.js إجراء استدعاءات أقل إلى zlib
لأنها ستكون قادرة علي معالجة المزيد من البيانات عند كل عملية كتابة. لذا، سيكون هذا عاملًا آخر يؤثر على السرعة، على حساب استخدام الذاكرة.
التدفق (Flushing)
سيؤدي استدعاء .flush()
علي دفق الضغط لأن يُعيد zlib
المُخرَج بقدر الإمكان حاليًا. وقد يأتي ذلك على حساب جودة الضغط المتدهورة، ولكن قد يكون ذلك مفيدًا عند الحاجة لأن تكون البيانات متاحة في أقرب وقت ممكن.
في المثال التالي ، يُستخدم flush()
التابع لكتابة استجابة HTTP جزئية مضغوطة إلى العميل:
const zlib = require('zlib');
const http = require('http');
http.createServer((request, response) => {
// من أجل التبسيط، حُذفت الفحوص الخاصة بـ Accept-Encoding.
response.writeHead(200, { 'content-encoding': 'gzip' });
const output = zlib.createGzip();
output.pipe(response);
setInterval(() => {
output.write(`The current time is ${Date()}\n`, () => {
// مٌررت البيانات إلى zlib، ولكن قد تقرر خوارزمية الضغط
// تخزين البيانات مؤقتًا للحصول على ضغط أكثر فعالية.
// سيجعل استدعاء .flush() البيانات متاحة بمجرد
// أن يكون العميل جاهزًا لتلقيها.
output.flush();
});
}, 1000);
}).listen(1337);
الثوابت (Constants)
أُضيف مع الإصدار: v0.5.8.
جميع الثوابت المُعرَّفة في zlib.h
تكون مُعرَّفة أيضًا في require('zlib').constants
. في المسار العادي للعمليات، لن يكون من الضروري استخدام هذه الثوابت. وهي موثقة بحيث لا يكون وجودها مفاجئًا. هذا المقطع مأخوذ تقريبًا مباشرةً من وثائق zlib. راجع https://zlib.net/manual.htmlConstants لمزيد من التفاصيل.
في السابق، كانت الثوابت متوفرة مباشرة من require('zlib')
، على سبيل المثال zlib.Z_NO_FLUSH
. لا يزال الوصول إلى الثوابت مباشرة من الوحدة ممكنًا حاليًا ولكنه مهمل.
قيم التدفق flush المسموح بها.
zlib.constants.Z_NO_FLUSH
zlib.constants.Z_PARTIAL_FLUSH
zlib.constants.Z_SYNC_FLUSH
zlib.constants.Z_FULL_FLUSH
zlib.constants.Z_FINISH
zlib.constants.Z_BLOCK
zlib.constants.Z_TREES
الرموز المُعادة لدوال الضغط وفك الضغط. القيم السالبة أخطاء، وتستخدم القيم الموجبة للأحداث الخاصة ولكن العادية.
zlib.constants.Z_OK
zlib.constants.Z_STREAM_END
zlib.constants.Z_NEED_DICT
zlib.constants.Z_ERRNO
zlib.constants.Z_STREAM_ERROR
zlib.constants.Z_DATA_ERROR
zlib.constants.Z_MEM_ERROR
zlib.constants.Z_BUF_ERROR
zlib.constants.Z_VERSION_ERROR
مستويات الضغط.
zlib.constants.Z_NO_COMPRESSION
zlib.constants.Z_BEST_SPEED
zlib.constants.Z_BEST_COMPRESSION
zlib.constants.Z_DEFAULT_COMPRESSION
استراتيجية الضغط.
zlib.constants.Z_FILTERED
zlib.constants.Z_HUFFMAN_ONLY
zlib.constants.Z_RLE
zlib.constants.Z_FIXED
zlib.constants.Z_DEFAULT_STRATEGY
الصنف Options
سجل التغييرات
الإصدار | التغييرات |
---|---|
v9.4.0 | يمكن أن يكون الخيار dictionary من النوع ArrayBuffer .
|
v8.0.0 | يمكن أن يكون الخيار dictionary من النوع Uint8Array .
|
v5.11.0 | بداية دعم finishFlush .
|
v0.11.1 | أُضيف مع الإصدار: v0.11.1 |
يأخذ كل صنف كائن options
. جميع الخيارات اختيارية.
لاحظ أن بعض الخيارات تكون متاحة فقط عند الضغط، وتُتجاهل من أصناف فك الضغط.
-
flush
من النوع<integer>
، القيمة الافتراضية:zlib.constants.Z_NO_FLUSH
. -
finishFlush
من النوع<integer>
، القيمة الافتراضية:zlib.constants.Z_FINISH
. -
chunksize
من النوع<integer>
القيمة الافتراضية: 16 * 1024
. -
windowbits
من النوع<integer>
. -
level
من النوع<integer>
(الضغط فقط). -
memLevel
من النوع<integer>
(الضغط فقط). -
strategy
من النوع<integer>
(الضغط فقط). -
dictionary
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
(الانكماش/التضخيم فقط، قاموس فارغ بشكل افتراضي). info
من النوع<boolean>
(إذا كانtrue
، يعيد كائن معbuffer
وengine
).
راجع وصف deflateinit2
و inflateinit2
على الرابط https://zlib.net/manual.htmlAdvanced للحصول علي مزيد من المعلومات.
الصنف zlib.Deflate
أُضيف مع الإصدار: v0.5.8.
ضغط البيانات باستخدام deflate.
الصنف zlib.DeflateRaw
أُضيف مع الإصدار: v0.5.8.
ضغط البيانات باستخدام deflate، وعدم إلحاق ترويسة zlib
.
الصنف zlib.Gunzip
سجل التغييرات
الإصدار | التغييرات |
---|---|
v6.0.0 | ستؤدي المُهملات الخلفية في نهاية دفق الإدخال الآن إلى إنطلاق حدث 'error' .
|
v5.9.0 | بداية دعم أعضاء ملف gzip متسلسلة متعددة . |
v5.0.0 | سيؤدي الآن تدفق مبتور إلى إنطلاق حدث 'error' .
|
v0.5.8 | أُضيف مع الإصدار: v0.5.8. |
فك ضغط تيار gzip.
الصنف zlib.Gzip
أُضيف مع الإصدار: v0.5.8.
ضغط البيانات باستخدام gzip.
الصنف zlib.Inflate
سجل التغييرات
الإصدار | التغييرات |
---|---|
v5.0.0 | سيؤدي الآن تدفق مبتور إلى إنطلاق حدث 'error' .
|
v0.5.8 | أُضيف مع الإصدار: v0.5.8. |
فك ضغط تيار انكماش.
الصنف: zlib.InflateRaw
[المصدر]
سجل التغييرات
الإصدار | التغييرات |
---|---|
v6.8.0 | بداية دعم القواميس المخصصة بواسطة InflateRaw .
|
v5.0.0 | سيؤدي الآن تدفق مبتور إلى إنطلاق حدث 'error' .
|
v0.5.8 | أُضيف مع الإصدار: v0.5.8. |
فك ضغط تيار انكماش خام.
الصنف zlib.Unzip
أُضيف مع الإصدار: v0.5.8.
فك ضغط دفق Gzip- أو Deflate- المضغوط بالكشف التلقائي عن الترويسة.
الصنف zlib.Zlib
أُضيف مع الإصدار: v0.5.8.
لا تُصدَّر بواسطة الوحدة zlib
. وهو موثق هنا لأنه هو الصنف الأساسي من أصناف الضواغط/وفاكّي الضغط.
يرث هذا الصنف من stream.Transform
، سامحًا لكائنات zlib
بأن تُستخدم في الأنابيب وعمليات الدفق المماثلة.
zlib. bytesRead
أُضيف مع الإصدار: v8.1.0، وأُهمِل مع الإصدار: v10.0.0.
مؤشر الاستقرار: 0 - مُهمَل: يُستخدم zlib.bytesWritten
بدلًا منه.
- من النوع <number>.
اسم مستعار مُهمل للخاصية zlib.bytesWritten
. اُختير هذا الاسم المبتكر لأنه من المنطقي أيضا تفسير القيمة بعدد البايتات المقروءة بواسطة المُحرك، ولكنه غير متناسق مع التدفقات الأخرى في Node.js التي تعرض القيم تحت هذه الأسماء.
zlib.bytesWritten
أُضيفت مع الإصدار: v10.0.0.
- من النوع <number>.
تحدد الخاصية zlib.bytesWritten
عدد وحدات البايت المكتوبة إلى المُحرِّك قبل معالجة وحدات البايت (مضغوطة أو غير مضغوطة، بما يتناسب مع الصنف المشتق).
zlib.close([callback])
أُضيف مع الإصدار: v0.9.4.
-
callback
من النوع<Function>
.
اغلاق المُعالج الأساسي.
zlib.flush([kind, ]callback)
أُضيف مع الإصدار: v0.5.8.
-
kind
القيمة الافتراضية:zlib.constants.Z_FULL_FLUSH
.
-
callback
من النوع<Function>
.
تدفق البيانات المُعلَّقة. على عكس ما يبدو، يؤثر التدفق المبكر سلبًا على فاعلية خوارزمية الضغط.
استدعاء هذا التابع يدفع البيانات من الحالة zlib
الداخلية، ولا يدفع أي نوع علي مستوي التدفقات. وبدلًا من ذلك، فإنه يتصرف مثل استدعاءٍ عادي للتابع .write()
، أي أنه سيُضاف إلى قائمة الانتظار وراء الكتابات الأخرى المعلقة وسينتج مُخرجات فقط عند قراءة البيانات من الدفق.
zlib.params(level, strategy, callback)
أُضيف مع الإصدار: v0.11.4.
-
level
من النوع<integer>
. -
strategy
من النوع<integer>
. -
callback
من النوع<Function>
.
تحديث مستوى الضغط واستراتيجية الضغط بشكل حيوي. ينطبق فقط على خوارزمية الانكماش.
zlib.reset()
أُضيف مع الإصدار: v0.7.0.
أعاده تعيين الضاغط/إلغاء ضغط إلى إعدادات المصنع الافتراضية. تنطبق فقط على خوارزميات inflate و deflate.
zlib.constants
أضيف مع الإصدار: v 7.0.0.
يوفر كائن لعد الثوابت المرتبطة بـ Zlib.
zlib.createDeflate([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن Deflate
جديد ويُعيده.
zlib.createDeflateRaw([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
يُنشئ كائن DeflateRaw
جديد ويُعيده.
غيرت ترقية zlib من الإصدار 1.2.8 إلى 1.2.11 من سلوكه عند ضبط windowBits
بالقيمة 8 لتدفقات الانكماش الخام. سيضبط zlib قيمة windowBits
إلى 9 تلقائيا إذا ضُبِط في البداية إلي 8. ستُجري الإصدارات الأحدث من zlib استثناءً، بحيث تستعيد Node.js السلوك الأصلي لترقية القيمة 8 إلى 9، إذ يُنتِج تمرير windowBits = 9
إلى zlib فعليًا دفقًا مضغوطًا يستخدم إطار 8-بت فقط بشكل فعَّال.
zlib.createGunzip([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن Gunzip
جديد ويُعيده.
zlib.createGzip([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن Gzip
جديد ويُعيده.
zlib.createInflate([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن Inflate
جديد ويُعيده.
zlib.createInflateRaw([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن InflateRaw
جديد ويُعيده.
zlib.createUnzip([options])
أُضيف مع الإصدار: v0.5.8.
-
options
من النوع<Object>
.
ينشئ كائن Unzip
جديد ويُعيده.
توابع الملاءمة
تتخذ جميع هذه التوابع أيًا من Buffer أو TypedArray
أو DataView
أو ArrayBuffer
أو <string>
كوسيط أول، ويكون الوسيط الثاني اختياريًا لتوفير الخيارات لأصناف zlib
، وستُسدعي دالة رد الاتصال المُعطاة مع callback(error, result)
.
ولكل تابع نظير *Sync
، والذي يقبل نفس الوسائط، ولكن من دون دالة رد الاتصال.
zlib.deflate(buffer[, options], callback)
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.deflateSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
فك ضغط كتلة من البيانات باستخدام Deflate.
zlib.deflateRaw(buffer[, options], callback)
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.deflateRawSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
ضغط كتلة من البيانات باستخدام DeflateRaw
.
zlib.gunzip(buffer[, options], callback)
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.gunzipSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
فك ضغط كتلة من البيانات باستخدام Gunzip
.
zlib.gzip(buffer[, options], callback)
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
.-
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.gzipSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
ضغط كتلة من البيانات باستخدام Gzip
.
zlib.inflate(buffer[, options], callback)
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
.-
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.inflateSync(buffer[, options])
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
.-
options
من النوع<Object>
.
فك ضغط كتلة من البيانات باستخدام Inflate
.
zlib.inflateRaw(buffer[, options], callback)
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
.-
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.inflateRawSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
فك ضغط كتلة من البيانات باستخدام InflateRaw
.
zlib.unzip(buffer[, options], callback)
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
.-
options
من النوع<Object>
. -
callback
من النوع<Function>
.
zlib.unzipSync(buffer[, options])
-
buffer
من النوع <Buffer>
|<TypedArray>
|<DataView>
|<ArrayBuffer>
|<string>
. -
options
من النوع<Object>
.
فك ضغط كتلة من البيانات باستخدام Unzip
.