Comprehensive functionality for extracting files and directories from ZIP archives to disk with various options for path handling, permissions, and extraction modes.
Extract individual files or directories from the archive to a target location with fine-grained control over the extraction process.
/**
* Extract single entry to target path
* @param {string|ZipEntry} entry - Entry name or ZipEntry object to extract
* @param {string} targetPath - Target extraction directory
* @param {boolean} [maintainEntryPath] - Keep original directory structure (default: true)
* @param {boolean} [overwrite] - Overwrite existing files (default: false)
* @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
* @param {string} [outFileName] - Custom output filename (files only)
* @returns {boolean} True if extraction succeeded
*/
extractEntryTo(entry, targetPath, maintainEntryPath, overwrite, keepOriginalPermission, outFileName);Usage Examples:
const AdmZip = require("adm-zip");
const zip = new AdmZip("./archive.zip");
// Basic file extraction
zip.extractEntryTo("documents/report.pdf", "./extracted/");
// Result: ./extracted/documents/report.pdf
// Extract file to root without directory structure
zip.extractEntryTo("documents/report.pdf", "./extracted/", false);
// Result: ./extracted/report.pdf
// Extract with custom filename
zip.extractEntryTo("data/config.json", "./settings/", false, true, false, "app-config.json");
// Result: ./settings/app-config.json
// Extract directory and all its contents
zip.extractEntryTo("images/", "./extracted/", true, true);
// Result: ./extracted/images/... (all files in images folder)
// Extract with permission preservation (Unix/Linux)
zip.extractEntryTo("scripts/deploy.sh", "./bin/", false, true, true);
// Preserves executable permissions
// Extract using ZipEntry object
const entry = zip.getEntry("important.txt");
if (entry) {
zip.extractEntryTo(entry, "./backup/", true, false);
}Extract all contents of the archive to a target directory with global options.
/**
* Extract entire archive to target directory
* @param {string} targetPath - Target extraction directory
* @param {boolean} [overwrite] - Overwrite existing files (default: false)
* @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
* @param {string|Buffer} [pass] - Password for encrypted archives
*/
extractAllTo(targetPath, overwrite, keepOriginalPermission, pass);Usage Examples:
const zip = new AdmZip("./archive.zip");
// Basic full extraction
zip.extractAllTo("./extracted/");
// Extract with overwrite enabled
zip.extractAllTo("./extracted/", true);
// Extract preserving permissions
zip.extractAllTo("./extracted/", true, true);
// Extract password-protected archive
zip.extractAllTo("./extracted/", true, false, "secretpassword");
// Extract to absolute path
zip.extractAllTo("/home/user/backup/", true);
// Conditional extraction based on archive contents
const entries = zip.getEntries();
const hasImportantFiles = entries.some(entry => entry.entryName.includes('important'));
if (hasImportantFiles) {
zip.extractAllTo("./priority-extraction/", true, true);
} else {
zip.extractAllTo("./regular-extraction/", false);
}Extract all archive contents asynchronously with callback or Promise support for large archives.
/**
* Extract entire archive asynchronously
* @param {string} targetPath - Target extraction directory
* @param {boolean} [overwrite] - Overwrite existing files (default: false)
* @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
* @param {function} [callback] - Callback function (error). If omitted, returns Promise
* @returns {Promise|void} Promise if no callback provided
*/
extractAllToAsync(targetPath, overwrite, keepOriginalPermission, callback);Usage Examples:
const zip = new AdmZip("./large-archive.zip");
// Async extraction with callback
zip.extractAllToAsync("./extracted/", true, false, function(error) {
if (error) {
console.error("Extraction failed:", error);
} else {
console.log("Extraction completed successfully");
}
});
// Promise-based extraction
zip.extractAllToAsync("./extracted/", true, true)
.then(() => {
console.log("Archive extracted successfully");
// Continue with post-extraction tasks
})
.catch(error => {
console.error("Extraction error:", error);
});
// Using async/await
async function extractArchive() {
try {
await zip.extractAllToAsync("./target/", true, true);
console.log("Extraction complete");
// Verify extraction
const fs = require("fs");
const extractedFiles = fs.readdirSync("./target/");
console.log(`Extracted ${extractedFiles.length} items`);
} catch (error) {
console.error("Failed to extract:", error);
}
}
// Extract with progress monitoring
zip.extractAllToAsync("./progress-extraction/", true, false, function(error) {
if (error) {
console.error("Extraction failed:", error.message);
if (error.message.includes("Unable to create folder")) {
console.log("Check directory permissions");
}
if (error.message.includes("Unable to write file")) {
console.log("Check available disk space");
}
} else {
console.log("All files extracted successfully");
}
});Extract specific files based on patterns or conditions using entry filtering.
Usage Examples:
const zip = new AdmZip("./project.zip");
const entries = zip.getEntries();
// Extract only JavaScript files
entries.forEach(entry => {
if (entry.entryName.endsWith('.js') && !entry.isDirectory) {
zip.extractEntryTo(entry, "./js-files/", false, true);
}
});
// Extract files from specific directory
entries.forEach(entry => {
if (entry.entryName.startsWith('src/') && !entry.isDirectory) {
zip.extractEntryTo(entry, "./source/", true, true);
}
});
// Extract files by size (smaller than 1MB)
entries.forEach(entry => {
if (entry.header.size < 1024 * 1024 && !entry.isDirectory) {
zip.extractEntryTo(entry, "./small-files/", false, true);
console.log(`Extracted: ${entry.entryName} (${entry.header.size} bytes)`);
}
});
// Extract files modified after specific date
const cutoffDate = new Date('2023-01-01');
entries.forEach(entry => {
if (entry.header.time > cutoffDate && !entry.isDirectory) {
zip.extractEntryTo(entry, "./recent-files/", true, true);
}
});
// Extract with custom naming scheme
entries.forEach(entry => {
if (entry.entryName.endsWith('.log') && !entry.isDirectory) {
const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
const customName = `${timestamp}_${entry.entryName.replace('/', '_')}`;
zip.extractEntryTo(entry, "./logs/", false, true, false, customName);
}
});Extract files with content validation and error handling.
Usage Examples:
const zip = new AdmZip("./data.zip");
const path = require("path");
const fs = require("fs");
// Extract with content validation
function extractWithValidation(entryName, targetPath) {
try {
const entry = zip.getEntry(entryName);
if (!entry) {
console.log(`Entry not found: ${entryName}`);
return false;
}
// Check if it's a valid file (not too large)
if (entry.header.size > 100 * 1024 * 1024) { // 100MB limit
console.log(`File too large: ${entryName} (${entry.header.size} bytes)`);
return false;
}
// Extract the file
const success = zip.extractEntryTo(entry, targetPath, true, true);
if (success) {
// Verify extraction
const extractedPath = path.join(targetPath, entry.entryName);
if (fs.existsSync(extractedPath)) {
const extractedSize = fs.statSync(extractedPath).size;
if (extractedSize === entry.header.size) {
console.log(`Successfully extracted: ${entryName}`);
return true;
} else {
console.log(`Size mismatch for: ${entryName}`);
return false;
}
}
}
return false;
} catch (error) {
console.error(`Error extracting ${entryName}:`, error);
return false;
}
}
// Extract important files with validation
const importantFiles = ['config.json', 'data/users.csv', 'assets/logo.png'];
importantFiles.forEach(file => {
extractWithValidation(file, './verified-extraction/');
});
// Batch extraction with error tracking
function extractBatch() {
const entries = zip.getEntries();
const results = { success: 0, failed: 0, errors: [] };
entries.forEach(entry => {
if (!entry.isDirectory) {
try {
const success = zip.extractEntryTo(entry, './batch-extraction/', true, true);
if (success) {
results.success++;
} else {
results.failed++;
results.errors.push(`Failed to extract: ${entry.entryName}`);
}
} catch (error) {
results.failed++;
results.errors.push(`Error extracting ${entry.entryName}: ${error.message}`);
}
}
});
console.log(`Extraction complete: ${results.success} success, ${results.failed} failed`);
if (results.errors.length > 0) {
console.log("Errors:", results.errors);
}
return results;
}
const batchResults = extractBatch();Handle different file systems and path conventions during extraction.
Usage Examples:
const zip = new AdmZip("./cross-platform.zip");
const path = require("path");
const os = require("os");
// Platform-aware extraction
function extractForPlatform(targetDir) {
const entries = zip.getEntries();
entries.forEach(entry => {
if (!entry.isDirectory) {
// Normalize path separators for current platform
let normalizedPath = entry.entryName.replace(/\\/g, '/');
// Handle platform-specific restrictions
if (os.platform() === 'win32') {
// Windows: handle reserved names and long paths
const invalidChars = /[<>:"|?*]/g;
normalizedPath = normalizedPath.replace(invalidChars, '_');
// Avoid reserved names like CON, PRN, etc.
const parts = normalizedPath.split('/');
const fileName = parts[parts.length - 1];
const reservedNames = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'LPT1'];
if (reservedNames.includes(fileName.toUpperCase().split('.')[0])) {
parts[parts.length - 1] = '_' + fileName;
normalizedPath = parts.join('/');
}
}
// Create safe target path
const targetPath = path.join(targetDir, normalizedPath);
const targetDirectory = path.dirname(targetPath);
// Ensure target directory exists
const fs = require("fs");
fs.mkdirSync(targetDirectory, { recursive: true });
// Extract with appropriate permissions
const keepPermissions = os.platform() !== 'win32';
zip.extractEntryTo(entry, targetDir, true, true, keepPermissions);
}
});
}
extractForPlatform('./platform-safe-extraction/');