< All Topics

Unzip multiple files

Overview

The Unzip Files function extracts all files from a ZIP archive immediately and returns the list of extracted file paths. This is the simplest extraction operation in Archive Manager Pro, perfect for quick file extraction tasks where blocking execution is acceptable.

Function Description

Node Name: Unzip Files
Category: Archive Manager
Type: Synchronous (blocking operation)

Extracts all files from a ZIP archive and returns an array containing the full paths to all extracted files. The operation completes immediately and execution blocks until all files are extracted.

Blueprint Usage

Input Parameters

ParameterTypeDescription
Path to ZipStringFull absolute path to the ZIP file you want to extract
Delete After ExtractionBooleanIf true, deletes the ZIP file after successful extraction

Output Parameters

ParameterTypeDescription
Path to FilesArray of StringsArray containing full paths to all extracted files
Return ValueBooleantrue if extraction succeeded, false if it failed

Blueprint Setup Steps

  1. Add the Unzip Files Node
    • Right-click in the Event Graph → Search for “Unzip Files”
    • Add the Unzip Files node from the Archive Manager category
  2. Configure Input
    • Path to ZipF:\Repos\tests\ArchiveManager\twofiles.zip
    • Delete After Extraction: ☐ Unchecked (keep original ZIP file)
  3. Process Extracted Files
    • Connect Path to Files array to a For Each Loop node
    • Connect Array Element to Print String to display each file path
    • Connect Completed output to final status message
  4. Handle Success/Failure
    • Optionally check Return Value for success confirmation
    • Use Get Last Archive Error if extraction fails

Example Blueprint Setup

C++ Usage

Basic Implementation

#include "ArchiveManagerBPLibrary.h"

// Synchronous extraction
FString ZipPath = TEXT("C:/Archives/DocumentBundle.zip");
TArray<FString> ExtractedFiles;
bool DeleteZipAfter = false;

bool Success = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, DeleteZipAfter);

if (Success)
{
    UE_LOG(LogTemp, Log, TEXT("Successfully extracted %d files:"), ExtractedFiles.Num());
    
    // Process each extracted file
    for (const FString& FilePath : ExtractedFiles)
    {
        UE_LOG(LogTemp, Log, TEXT("  - %s"), *FilePath);
        ProcessExtractedFile(FilePath);
    }
}
else
{
    FString Error = UArchiveManagerBPLibrary::GetLastArchiveError();
    UE_LOG(LogTemp, Error, TEXT("Extraction failed: %s"), *Error);
}

Advanced File Processing

class MYGAME_API FFileExtractor
{
public:
    // Extract and categorize files by type
    static bool ExtractAndCategorizeFiles(const FString& ZipPath, TMap<FString, TArray<FString>>& CategorizedFiles)
    {
        TArray<FString> ExtractedFiles;
        bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
        
        if (!bSuccess)
        {
            UE_LOG(LogTemp, Error, TEXT("Failed to extract archive: %s"), *ZipPath);
            return false;
        }
        
        // Categorize files by extension
        for (const FString& FilePath : ExtractedFiles)
        {
            FString Extension = FPaths::GetExtension(FilePath).ToLower();
            
            if (!CategorizedFiles.Contains(Extension))
            {
                CategorizedFiles.Add(Extension, TArray<FString>());
            }
            
            CategorizedFiles[Extension].Add(FilePath);
        }
        
        // Log categorization results
        for (const auto& Category : CategorizedFiles)
        {
            UE_LOG(LogTemp, Log, TEXT("Found %d files with extension '%s'"), 
                Category.Value.Num(), *Category.Key);
        }
        
        return true;
    }
    
    // Extract with file validation
    static TArray<FString> ExtractWithValidation(const FString& ZipPath, const TArray<FString>& ExpectedFiles)
    {
        TArray<FString> ExtractedFiles;
        TArray<FString> ValidatedFiles;
        
        bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
        
        if (!bSuccess)
        {
            UE_LOG(LogTemp, Error, TEXT("Extraction failed"));
            return ValidatedFiles;
        }
        
        // Validate extracted files against expected list
        for (const FString& ExpectedFile : ExpectedFiles)
        {
            bool bFound = false;
            for (const FString& ExtractedFile : ExtractedFiles)
            {
                if (FPaths::GetCleanFilename(ExtractedFile) == ExpectedFile)
                {
                    ValidatedFiles.Add(ExtractedFile);
                    bFound = true;
                    break;
                }
            }
            
            if (!bFound)
            {
                UE_LOG(LogTemp, Warning, TEXT("Expected file not found: %s"), *ExpectedFile);
            }
        }
        
        UE_LOG(LogTemp, Log, TEXT("Validated %d of %d expected files"), 
            ValidatedFiles.Num(), ExpectedFiles.Num());
        
        return ValidatedFiles;
    }
    
    // Extract to specific directory
    static bool ExtractToDirectory(const FString& ZipPath, const FString& TargetDirectory)
    {
        // Note: The plugin extracts to the same directory as the ZIP file by default
        // This function moves files to a target directory after extraction
        
        TArray<FString> ExtractedFiles;
        bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
        
        if (!bSuccess)
        {
            return false;
        }
        
        // Ensure target directory exists
        if (!FPaths::DirectoryExists(TargetDirectory))
        {
            IFileManager::Get().MakeDirectory(*TargetDirectory, true);
        }
        
        // Move extracted files to target directory
        TArray<FString> MovedFiles;
        for (const FString& SourcePath : ExtractedFiles)
        {
            FString FileName = FPaths::GetCleanFilename(SourcePath);
            FString TargetPath = TargetDirectory / FileName;
            
            if (IFileManager::Get().Move(*TargetPath, *SourcePath))
            {
                MovedFiles.Add(TargetPath);
                UE_LOG(LogTemp, Log, TEXT("Moved: %s -> %s"), *SourcePath, *TargetPath);
            }
            else
            {
                UE_LOG(LogTemp, Error, TEXT("Failed to move: %s"), *SourcePath);
            }
        }
        
        UE_LOG(LogTemp, Log, TEXT("Successfully moved %d files to %s"), 
            MovedFiles.Num(), *TargetDirectory);
        
        return MovedFiles.Num() == ExtractedFiles.Num();
    }
};

Game Asset Loading System

UCLASS(BlueprintType)
class MYGAME_API UAssetPackageLoader : public UObject
{
    GENERATED_BODY()
    
public:
    // Load game asset package from ZIP
    UFUNCTION(BlueprintCallable, Category = "Asset Loading")
    bool LoadAssetPackage(const FString& PackageZipPath, FAssetPackageInfo& PackageInfo)
    {
        TArray<FString> ExtractedFiles;
        bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(PackageZipPath, ExtractedFiles, false);
        
        if (!bSuccess)
        {
            UE_LOG(LogTemp, Error, TEXT("Failed to extract asset package: %s"), *PackageZipPath);
            return false;
        }
        
        // Process extracted files
        PackageInfo.PackageName = FPaths::GetBaseFilename(PackageZipPath);
        PackageInfo.ExtractedFiles = ExtractedFiles;
        
        for (const FString& FilePath : ExtractedFiles)
        {
            FString Extension = FPaths::GetExtension(FilePath).ToLower();
            
            if (Extension == TEXT("uasset"))
            {
                PackageInfo.AssetFiles.Add(FilePath);
            }
            else if (Extension == TEXT("umap"))
            {
                PackageInfo.MapFiles.Add(FilePath);
            }
            else if (Extension == TEXT("json"))
            {
                // Load package metadata
                LoadPackageMetadata(FilePath, PackageInfo);
            }
            else if (Extension == TEXT("png") || Extension == TEXT("jpg"))
            {
                PackageInfo.TextureFiles.Add(FilePath);
            }
        }
        
        UE_LOG(LogTemp, Log, TEXT("Loaded package '%s': %d assets, %d maps, %d textures"), 
            *PackageInfo.PackageName, 
            PackageInfo.AssetFiles.Num(),
            PackageInfo.MapFiles.Num(), 
            PackageInfo.TextureFiles.Num());
        
        // Register package with asset manager
        RegisterAssetPackage(PackageInfo);
        
        return true;
    }
    
    // Batch process multiple packages
    UFUNCTION(BlueprintCallable, Category = "Asset Loading")
    int32 LoadMultiplePackages(const TArray<FString>& PackageZipPaths)
    {
        int32 SuccessCount = 0;
        
        for (const FString& ZipPath : PackageZipPaths)
        {
            FAssetPackageInfo PackageInfo;
            if (LoadAssetPackage(ZipPath, PackageInfo))
            {
                SuccessCount++;
            }
        }
        
        UE_LOG(LogTemp, Log, TEXT("Successfully loaded %d of %d packages"), 
            SuccessCount, PackageZipPaths.Num());
        
        return SuccessCount;
    }

private:
    void LoadPackageMetadata(const FString& JsonPath, FAssetPackageInfo& PackageInfo) { /* Implementation */ }
    void RegisterAssetPackage(const FAssetPackageInfo& PackageInfo) { /* Implementation */ }
};

// Supporting structure
USTRUCT(BlueprintType)
struct FAssetPackageInfo
{
    GENERATED_BODY()
    
    UPROPERTY(BlueprintReadOnly)
    FString PackageName;
    
    UPROPERTY(BlueprintReadOnly)
    TArray<FString> ExtractedFiles;
    
    UPROPERTY(BlueprintReadOnly)
    TArray<FString> AssetFiles;
    
    UPROPERTY(BlueprintReadOnly)
    TArray<FString> MapFiles;
    
    UPROPERTY(BlueprintReadOnly)
    TArray<FString> TextureFiles;
    
    UPROPERTY(BlueprintReadOnly)
    FString Version;
    
    UPROPERTY(BlueprintReadOnly)
    FString Description;
};

Simple Utility Functions

// Quick extraction utility
TArray<FString> QuickExtract(const FString& ZipPath)
{
    TArray<FString> ExtractedFiles;
    UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
    return ExtractedFiles;
}

// Check what's inside a ZIP without extracting
bool PreviewZipContents(const FString& ZipPath, TArray<FString>& FileList)
{
    // Note: This would require additional implementation to read ZIP directory
    // For now, we extract to get the file list
    TArray<FString> ExtractedFiles;
    bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
    
    if (bSuccess)
    {
        // Convert full paths to just filenames for preview
        for (const FString& FullPath : ExtractedFiles)
        {
            FileList.Add(FPaths::GetCleanFilename(FullPath));
        }
    }
    
    return bSuccess;
}

// Extract and count files by type
void AnalyzeExtractedFiles(const FString& ZipPath)
{
    TArray<FString> ExtractedFiles;
    bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
    
    if (bSuccess)
    {
        TMap<FString, int32> ExtensionCounts;
        
        for (const FString& FilePath : ExtractedFiles)
        {
            FString Extension = FPaths::GetExtension(FilePath).ToLower();
            ExtensionCounts.FindOrAdd(Extension)++;
        }
        
        UE_LOG(LogTemp, Log, TEXT("Extracted %d files from %s:"), ExtractedFiles.Num(), *ZipPath);
        for (const auto& Pair : ExtensionCounts)
        {
            UE_LOG(LogTemp, Log, TEXT("  %s: %d files"), *Pair.Key, Pair.Value);
        }
    }
}

Common Use Cases

Game Development

  • Asset Package Loading: Extract game content packages
  • Save Game Import: Extract backup save files
  • Configuration Loading: Extract settings and configuration files
  • Resource Bundles: Extract localization or texture packages

Application Development

  • Data Import: Extract CSV, JSON, or XML data files
  • Document Processing: Extract document bundles for processing
  • Template Extraction: Extract project templates or themes
  • Backup Restoration: Extract backed-up application data

Best Practices

Performance Considerations

  1. Use for small to medium archives (< 50MB, < 100 files)
  2. Consider async version for larger archives or UI responsiveness
  3. Process files incrementally in the For Each Loop
  4. Clean up extracted files when no longer needed

Error Handling

  1. Always check Return Value before processing files
  2. Validate ZIP file exists before extraction
  3. Handle insufficient disk space gracefully
  4. Use Get Last Archive Error for specific error information

File Management

  1. Validate extracted file paths before processing
  2. Check file permissions on extracted files
  3. Handle duplicate filenames appropriately
  4. Monitor disk space during extraction

Extraction Behavior

  • Extraction Location: Files are extracted to the same directory as the ZIP file
  • Filename Preservation: Original filenames and extensions are preserved
  • Directory Structure: Flattened – subdirectories in ZIP become part of filename
  • Overwrite Behavior: Existing files with same names are overwritten

Performance Notes

  • Synchronous operation: Blocks execution until all files are extracted
  • Memory usage: Moderate – files are extracted to disk, not loaded into memory
  • File I/O: Sequential file extraction, optimized for reliability over speed
  • Thread safety: Safe to call from main thread, but will block UI updates
Table of Contents