Zlib moduli
Zlib moduliga kirish
Zlib moduli zlib va brotli siqish kutubxonalariga ulanishlarni ta’minlaydi, bu sizga quyidagilarga imkon beradi:
- Fayllar va ma’lumotlar oqimlarini siqish va ochish
- HTTP siqishni amalga oshirish
- Siqilgan fayl formatlari (.gz, .zip) bilan ishlash
- Veb-ilovalarda tarmoqli kengligidan foydalanishni optimallashtirish
Zlib modulini import qilish
const zlib = require('zlib');
Siqish usullari
Zlib moduli bir nechta siqish usullarini qo‘llab-quvvatlaydi:
| Metod | Tavsif |
|---|---|
| Gzip/Gunzip | Eng ko‘p ishlatiladigan siqish formati, ayniqsa veb-kontent uchun |
| O‘chirish/shishirmoq | Sarlavhalar yoki nazorat summalarisiz xom deflatsiya algoritmi |
| DeflateRaw/InflateRaw | Maxsus sarlavha va nazorat summasini qayta ishlash bilan xom deflatsiya algoritmi |
| Brotli | Yaxshiroq siqish darajasini taklif qiluvchi zamonaviy siqish algoritmi (Node.js 10.16.0 da qo‘shilgan) |
Asosiy siqilish va dekompressiya
Callback-lardan foydalanish
const zlib = require('zlib');
const input = 'This is some text that will be compressed using the zlib module in Node.js.';
// Compress data using gzip
zlib.gzip(input, (err, compressed) => {
if (err) {
console.error('Compression error:', err);
return;
}
console.log('Original size:', input.length, 'bytes');
console.log('Compressed size:', compressed.length, 'bytes');
console.log('Compression ratio:', Math.round(100 - (compressed.length / input.length * 100)) + '%');
// Decompress the data
zlib.gunzip(compressed, (err, decompressed) => {
if (err) {
console.error('Decompression error:', err);
return;
}
console.log('Decompressed data:', decompressed.toString());
console.log('Successfully decompressed:', input === decompressed.toString());
});
});
Promiselardan foydalanish
const zlib = require('zlib');
const { promisify } = require('util');
// Convert callback-based functions to promise-based
const gzipPromise = promisify(zlib.gzip);
const gunzipPromise = promisify(zlib.gunzip);
async function compressAndDecompress(input) {
try {
// Compress
const compressed = await gzipPromise(input);
console.log('Original size:', input.length, 'bytes');
console.log('Compressed size:', compressed.length, 'bytes');
// Decompress
const decompressed = await gunzipPromise(compressed);
console.log('Decompressed data:', decompressed.toString());
console.log('Success:', input === decompressed.toString());
return compressed;
} catch (err) {
console.error('Error:', err);
}
}
// Example usage
const testData = 'This is some test data that will be compressed with the zlib module.';
compressAndDecompress(testData);
Streams bilan ishlash
Zlib moduli katta fayllar yoki ma’lumotlarni qayta ishlash uchun streamlar bilan ishlatilishi mumkin:
const zlib = require('zlib');
const fs = require('fs');
const path = require('path');
// Compress a file
function compressFile(inputPath) {
const outputPath = inputPath + '.gz';
// Create read and write streams
const input = fs.createReadStream(inputPath);
const output = fs.createWriteStream(outputPath);
// Create gzip transform stream
const gzip = zlib.createGzip();
// Pipe data through the compression stream
input.pipe(gzip).pipe(output);
// Handle events
input.on('error', (err) => console.error('Input error:', err));
gzip.on('error', (err) => console.error('Compression error:', err));
output.on('error', (err) => console.error('Output error:', err));
output.on('finish', () => {
console.log(`File compressed successfully: ${outputPath}`);
// Get file sizes for comparison
const inputStats = fs.statSync(inputPath);
const outputStats = fs.statSync(outputPath);
console.log(`Original size: ${inputStats.size} bytes`);
console.log(`Compressed size: ${outputStats.size} bytes`);
console.log(`Compression ratio: ${Math.round(100 - (outputStats.size / inputStats.size * 100))}%`);
});
}
// Decompress a file
function decompressFile(inputPath) {
// Remove .gz extension for output path
const outputPath = inputPath.endsWith('.gz')
? inputPath.slice(0, -3)
: inputPath + '.uncompressed';
// Create streams
const input = fs.createReadStream(inputPath);
const output = fs.createWriteStream(outputPath);
const gunzip = zlib.createGunzip();
// Pipe data through decompression stream
input.pipe(gunzip).pipe(output);
// Handle events
input.on('error', (err) => console.error('Input error:', err));
gunzip.on('error', (err) => console.error('Decompression error:', err));
output.on('error', (err) => console.error('Output error:', err));
output.on('finish', () => {
console.log(`File decompressed successfully: ${outputPath}`);
});
}
// Example usage (assuming you have a text file)
// compressFile('example.txt');
// decompressFile('example.txt.gz');
// Note: Uncomment the above lines to actually run the compression/decompression
console.log('This example shows how to compress and decompress files using streams.');
console.log('Create a text file named "example.txt" and uncomment the function calls to test.');
Eslatma: Oqimlardan foydalanish katta fayllarni qayta ishlash uchun xotirani tejaydi, chunki butun faylni birdaniga xotiraga yuklash shart emas.
HTTP siqish
Zlib moduli odatda o‘tkazish qobiliyatini kamaytirish uchun HTTP siqish uchun ishlatiladi:
const http = require('http');
const zlib = require('zlib');
// Create an HTTP server with compression
const server = http.createServer((req, res) => {
// Sample response content
const responseBody = `
<!DOCTYPE html>
<html>
<head>
<title>Zlib Compression Example</title>
</head>
<body>
<h1>HTTP Compression with Zlib</h1>
<p>This content is being compressed with Gzip before sending to your browser.</p>
<p>Compression reduces bandwidth usage and improves page load times.</p>
${'<p>This paragraph is repeated to demonstrate compression efficiency.</p>'.repeat(50)}
</body>
</html>
`;
// Check if client accepts gzip encoding
const acceptEncoding = req.headers['accept-encoding'] || '';
// Set content type
res.setHeader('Content-Type', 'text/html');
// Compress response if client supports it
if (/\bgzip\b/.test(acceptEncoding)) {
// Client supports gzip
res.setHeader('Content-Encoding', 'gzip');
// Compress and send
zlib.gzip(responseBody, (err, compressed) => {
if (err) {
res.statusCode = 500;
res.end('Internal Server Error');
return;
}
res.end(compressed);
});
} else if (/\bdeflate\b/.test(acceptEncoding)) {
// Client supports deflate
res.setHeader('Content-Encoding', 'deflate');
// Compress and send
zlib.deflate(responseBody, (err, compressed) => {
if (err) {
res.statusCode = 500;
res.end('Internal Server Error');
return;
}
res.end(compressed);
});
} else {
// No compression supported
res.end(responseBody);
}
});
// Start server on port 8080
const PORT = 8080;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
console.log('Open this URL in your browser to see compression in action');
console.log('The browser will automatically decompress the content');
});
Brotli Compression bilan ishlash
Brotli zamonaviy siqish algoritmi bo‘lib, u ko‘pincha Gzip-ga qaraganda yaxshiroq siqish nisbatlariga erishadi:
const zlib = require('zlib');
// Sample data to compress
const input = 'This is some test data that will be compressed with different algorithms for comparison.'.repeat(20);
// Compare compression methods
function compareCompression() {
console.log(`Original data size: ${input.length} bytes`);
// Gzip compression
zlib.gzip(input, (err, gzipped) => {
if (err) {
console.error('Gzip error:', err);
return;
}
console.log(`Gzip size: ${gzipped.length} bytes (${Math.round(100 - (gzipped.length / input.length * 100))}% reduction)`);
// Deflate compression
zlib.deflate(input, (err, deflated) => {
if (err) {
console.error('Deflate error:', err);
return;
}
console.log(`Deflate size: ${deflated.length} bytes (${Math.round(100 - (deflated.length / input.length * 100))}% reduction)`);
// Brotli compression (if available)
if (typeof zlib.brotliCompress === 'function') {
zlib.brotliCompress(input, (err, brotli) => {
if (err) {
console.error('Brotli error:', err);
return;
}
console.log(`Brotli size: ${brotli.length} bytes (${Math.round(100 - (brotli.length / input.length * 100))}% reduction)`);
});
} else {
console.log('Brotli compression not available in this Node.js version');
}
});
});
}
// Run the comparison
compareCompression();
Misolni ishga tushirish »
Eslatma: Brotli siqish Node.js 10.16.0 va keyingi versiyalarida mavjud. Odatda u yaxshi siqish nisbatlariga erishadi, lekin Gzipga qaraganda sekinroq bo‘lishi mumkin.
Siqish imkoniyatlari
Siz siqish harakatini quyidagi variantlar bilan sozlashingiz mumkin:
const zlib = require('zlib');
const input = 'This is example content for compression with custom options.'.repeat(50);
// Test different compression levels
function testCompressionLevels() {
console.log(`Original size: ${input.length} bytes`);
// Default compression (level 6)
zlib.gzip(input, (err, compressed) => {
if (err) throw err;
console.log(`Default compression (level 6): ${compressed.length} bytes`);
// Fastest compression (level 1)
zlib.gzip(input, { level: 1 }, (err, fastCompressed) => {
if (err) throw err;
console.log(`Fast compression (level 1): ${fastCompressed.length} bytes`);
// Best compression (level 9)
zlib.gzip(input, { level: 9 }, (err, bestCompressed) => {
if (err) throw err;
console.log(`Best compression (level 9): ${bestCompressed.length} bytes`);
});
});
});
}
// Test compression with custom memory usage
function testMemoryLevels() {
// Memory levels: 1 (lowest) to 9 (highest)
zlib.gzip(input, { memLevel: 9 }, (err, compressed) => {
if (err) throw err;
console.log(`High memory usage (memLevel 9): ${compressed.length} bytes`);
zlib.gzip(input, { memLevel: 4 }, (err, lowMemCompressed) => {
if (err) throw err;
console.log(`Low memory usage (memLevel 4): ${lowMemCompressed.length} bytes`);
});
});
}
// Run tests
testCompressionLevels();
setTimeout(testMemoryLevels, 1000); // Slight delay to separate console output
Umumiy Zlib variantlari quyidagilarni o‘z ichiga oladi:
level: Siqish darajasi (0-9, 0=yo‘q, 9=eng yaxshi)memLevel: Xotiradan foydalanish (1-9, 1=eng past, 9=eng yuqori)strategy: Siqish strategiyasi (masalan, Z_DEFAULT_STRATEGY)dictionary: Siqish uchun oldindan belgilangan dictionarywindowBits: Oyna hajmi logarifmi
Xato bilan ishlash
Siqish bilan ishlashda xatolarni to‘g‘ri hal qilish juda muhim:
const zlib = require('zlib');
const fs = require('fs');
// Function to safely decompress data
function safeDecompress(compressedData) {
return new Promise((resolve, reject) => {
zlib.gunzip(compressedData, { finishFlush: zlib.constants.Z_SYNC_FLUSH }, (err, result) => {
if (err) {
// Handle specific error types
if (err.code === 'Z_DATA_ERROR') {
reject(new Error('Invalid or corrupt compressed data'));
} else if (err.code === 'Z_BUF_ERROR') {
reject(new Error('Incomplete compressed data'));
} else {
reject(err);
}
return;
}
resolve(result);
});
});
}
// Example usage with error handling
async function demonstrateErrorHandling() {
try {
// Valid compression
const validData = await zlib.gzipSync('This is valid data');
console.log('Successfully compressed valid data');
// Try to decompress valid data
const result = await safeDecompress(validData);
console.log('Successfully decompressed:', result.toString());
// Try to decompress invalid data
const invalidData = Buffer.from('This is not compressed data');
await safeDecompress(invalidData);
} catch (err) {
console.error('Error occurred:', err.message);
}
}
demonstrateErrorHandling();
Amaliy ilovalar
1. Jurnal fayllarini siqish
const zlib = require('zlib');
const fs = require('fs');
const path = require('path');
// Compress log files and add timestamp
function compressLogFile(logFilePath) {
// Generate output path with timestamp
const timestamp = new Date().toISOString().replace(/:/g, '-');
const basename = path.basename(logFilePath);
const outputPath = path.join(
path.dirname(logFilePath),
`${basename}-${timestamp}.gz`
);
// Create streams
const input = fs.createReadStream(logFilePath);
const output = fs.createWriteStream(outputPath);
const gzip = zlib.createGzip();
// Pipe the streams
input.pipe(gzip).pipe(output);
// Handle events
output.on('finish', () => {
console.log(`Log file compressed: ${outputPath}`);
// Optionally, clear the original log file
fs.writeFile(logFilePath, '', err => {
if (err) {
console.error(`Error clearing log file: ${err.message}`);
} else {
console.log(`Original log file cleared: ${logFilePath}`);
}
});
});
input.on('error', err => console.error(`Read error: ${err.message}`));
gzip.on('error', err => console.error(`Compression error: ${err.message}`));
output.on('error', err => console.error(`Write error: ${err.message}`));
}
// Example usage
// compressLogFile('server.log');
// Note: Uncomment the line above to compress an actual log file
console.log('This example shows how to compress log files with timestamps.');
2. API javobini siqish
const http = require('http');
const zlib = require('zlib');
// Sample API data (imagine this is from a database)
const apiData = {
users: Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
name: `User ${i + 1}`,
email: `user${i + 1}@example.com`,
role: i % 3 === 0 ? 'admin' : 'user',
created: new Date().toISOString(),
profile: {
bio: `This is a sample bio for user ${i + 1}. It contains some text to demonstrate compression.`,
interests: ['programming', 'reading', 'hiking', 'cooking', 'music'],
settings: {
notifications: true,
theme: 'dark',
language: 'en'
}
}
}))
};
// Create a simple API server
const server = http.createServer((req, res) => {
// Only handle GET requests to /api/users
if (req.method === 'GET' && req.url === '/api/users') {
// Convert data to JSON string
const jsonData = JSON.stringify(apiData);
// Check if client accepts compression
const acceptEncoding = req.headers['accept-encoding'] || '';
// Set JSON content type
res.setHeader('Content-Type', 'application/json');
// Compress based on accepted encoding
if (/\bgzip\b/.test(acceptEncoding)) {
res.setHeader('Content-Encoding', 'gzip');
// Compress and send
zlib.gzip(jsonData, (err, compressed) => {
if (err) {
res.statusCode = 500;
res.end(JSON.stringify({ error: 'Compression failed' }));
return;
}
console.log(`Original size: ${jsonData.length} bytes`);
console.log(`Compressed size: ${compressed.length} bytes`);
console.log(`Compression ratio: ${Math.round(100 - (compressed.length / jsonData.length * 100))}%`);
res.end(compressed);
});
} else {
// No compression
console.log(`Sending uncompressed response: ${jsonData.length} bytes`);
res.end(jsonData);
}
} else {
// Not found
res.statusCode = 404;
res.end(JSON.stringify({ error: 'Not found' }));
}
});
// Start server
const PORT = 8080;
server.listen(PORT, () => {
console.log(`API server running at http://localhost:${PORT}/`);
console.log('Test the API by visiting: http://localhost:8080/api/users');
});
Murakkab siqish texnikasi
1. Siqish strategiyalari
Zlib ma’lum turdagi ma’lumotlar uchun samaraliroq bo‘lishi mumkin bo‘lgan turli xil siqish strategiyalarini taklif qiladi:
const zlib = require('zlib');
// Sample data with repeated patterns (good for RLE)
const repeatedData = 'ABC'.repeat(1000);
// Test different compression strategies
function testStrategies(data) {
const strategies = [
{ name: 'DEFAULT_STRATEGY', value: zlib.constants.Z_DEFAULT_STRATEGY },
{ name: 'FILTERED', value: zlib.constants.Z_FILTERED },
{ name: 'HUFFMAN_ONLY', value: zlib.constants.Z_HUFFMAN_ONLY },
{ name: 'RLE', value: zlib.constants.Z_RLE },
{ name: 'FIXED', value: zlib.constants.Z_FIXED }
];
console.log(`Original size: ${data.length} bytes`);
strategies.forEach(({ name, value }) => {
const compressed = zlib.gzipSync(data, { strategy: value });
console.log(`${name.padEnd(20)}: ${compressed.length.toString().padEnd(5)} bytes`);
});
}
testStrategies(repeatedData);
2. Maxsus lug‘atlar
Muayyan ma’lumotlar namunalari uchun maxsus lug‘atlar siqishni nisbatini yaxshilashi mumkin:
const zlib = require('zlib');
// Create a custom dictionary with common terms
const dictionary = Buffer.from('username,password,email,first_name,last_name,created_at,updated_at,status,active,inactive,pending,admin,user,role,permissions');
// Sample data that benefits from the dictionary
const userData = JSON.stringify({
username: 'johndoe',
email: 'john@example.com',
first_name: 'John',
last_name: 'Doe',
role: 'admin',
status: 'active',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
});
// Compress with and without dictionary
const compressedWithout = zlib.deflateSync(userData);
const compressedWith = zlib.deflateSync(userData, { dictionary });
console.log('Original size:', Buffer.byteLength(userData), 'bytes');
console.log('Compressed without dictionary:', compressedWithout.length, 'bytes');
console.log('Compressed with dictionary:', compressedWith.length, 'bytes');
console.log('Improvement:', Math.round((1 - (compressedWith.length / compressedWithout.length)) * 100) + '%');
// Decompress with dictionary
const decompressed = zlib.inflateSync(compressedWith, { dictionary });
console.log('Decompressed matches original:', decompressed.toString() === userData);
3. Progressiv siqish
Mavjud bo‘lganda ma’lumotlarni qismlarga bo‘lib qayta ishlang:
const zlib = require('zlib');
const { Transform } = require('stream');
class ProgressTracker extends Transform {
constructor(options = {}) {
super(options);
this.processedBytes = 0;
this.startTime = Date.now();
}
_transform(chunk, encoding, callback) {
this.processedBytes += chunk.length;
const elapsed = (Date.now() - this.startTime) / 1000;
const rate = (this.processedBytes / 1024 / 1024 / elapsed).toFixed(2);
process.stdout.write(`\rProcessed: ${(this.processedBytes / 1024 / 1024).toFixed(2)} MB | ` +
`Rate: ${rate} MB/s`);
this.push(chunk);
callback();
}
}
// Simulate processing a large file
function processLargeFile() {
const gzip = zlib.createGzip({ level: 6 });
const progress = new ProgressTracker();
// Generate 100MB of random data
const data = Buffer.alloc(1024 * 1024 * 100);
// Create a readable stream from buffer
const { Readable } = require('stream');
const readable = Readable.from(data);
console.log('Starting compression...');
readable
.pipe(progress)
.pipe(gzip)
.pipe(process.stdout);
gzip.on('end', () => {
console.log('\nCompression complete!');
});
}
// Uncomment to run (creates a large file)
// processLargeFile();
Ishlash bo‘yicha mulohazalar
- Siqish darajasidagi kelishuvlar: Yuqori darajalar = yaxshiroq siqish, lekin sekinroq ishlov berish
- Xotiradan foydalanish: Siqish, ayniqsa, yuqori darajalarda xotirani ko‘p talab qilishi mumkin
- Qachon siqish kerak: Faqat siqilishdan foyda oladigan ma’lumotlarni (matn, JSON va boshqalar) siqish.
- Allaqachon siqilgan ma’lumotlar: allaqachon siqilgan fayllarni (rasmlar, videolar va h.k.) siqmang.
- Stream: Xotira muammolarini oldini olish uchun katta fayllar uchun oqimlardan foydalaning
- Mavzu pulidan foydalanish: Zlib operatsiyalari libuvning iplar hovuzidan foydalanadi; agar kerak bo‘lsa UV_THREADPOOL_SIZE bilan sozlang
Xulosa
Node.js Zlib moduli quyidagilar uchun muhim siqish va dekompressiya funksiyalarini taqdim etadi:
- Fayl o‘lchamlarini va tarmoqli kengligidan foydalanishni kamaytirish
- Siqilgan formatlar bilan ishlash
- HTTP siqishni amalga oshirish
- Streamlar yordamida katta ma’lumotlarni samarali qayta ishlash
Asosiy xususiyatlarga quyidagilar kiradi:
- Bir nechta siqish algoritmini qo‘llab-quvvatlash (Gzip, Deflate, Brotli)
- Sinxron va asinxron API
- Xotira samaradorligi uchun oqimga asoslangan ishlov berish
- Sozlanishi mumkin bo‘lgan siqish darajalari va imkoniyatlari
Zlib modulini tushunish Node.js ilovalarida ma’lumotlarni uzatish va saqlashni optimallashtirish uchun zarur.
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
