Skip to content

A .NET library for packaging and accessing resource files during build time and runtime.

License

coderbusy/luyao-resource-packer

Repository files navigation

LuYao.ResourcePacker

NuGet Version NuGet Downloads GitHub Stars

LuYao.ResourcePacker is a .NET library for packaging and accessing resource files during build time and runtime.

Features

  • Pack multiple resource files into a single .dat file during build
  • Intelligent tiered compression with GZip - automatic compression with sampling for optimal space/performance
  • Directory-based resource scanning (default: Resources directory)
  • MSBuild integration
  • Simple runtime API for resource access
  • Async support
  • Configurable through MSBuild properties
  • C# Source Generator for strongly-typed resource access with fixed "R" class (Android-style)

Installation

Package Manager Console

Install-Package LuYao.ResourcePacker.MSBuild
Install-Package LuYao.ResourcePacker

.NET CLI

dotnet add package LuYao.ResourcePacker.MSBuild
dotnet add package LuYao.ResourcePacker

Usage

1. Basic Setup

Place your resource files in the Resources directory:

Resources/
  ├── message.json
  ├── config.txt
  └── template.html

The resources will be automatically packed into a .dat file during build.

2. Runtime Access - Original API

Access resources at runtime using the ResourcePackageReader:

using LuYao.ResourcePacker;

// Read resources
using var reader = new ResourcePackageReader("YourAssembly.dat");

// Read as string
string content = await reader.ReadResourceAsStringAsync("message");

// Read as bytes
byte[] data = await reader.ReadResourceAsync("config");

// List all resources
foreach (var key in reader.ResourceKeys)
{
    Console.WriteLine(key);
}

3. Runtime Access - Strongly-Typed API

The source generator automatically creates an internal static class named R (Android-style) in the project's root namespace with strongly-typed access to your resources:

using LuYao.ResourcePacker;
using YourAssembly; // Import the namespace where the generated class resides

// Access resource keys as constants
Console.WriteLine(R.Keys.message);
Console.WriteLine(R.Keys.config);
Console.WriteLine(R.Keys.template);

// Read resources using generated methods
string message = await R.ReadMessageAsStringAsync();
byte[] configBytes = await R.ReadConfigAsync();
string template = await R.ReadTemplateAsStringAsync();

// Access the underlying reader if needed
ResourcePackageReader reader = R.Reader;

Benefits of the Strongly-Typed API:

  • IntelliSense support for resource names
  • Compile-time checking of resource names
  • No magic strings in your code
  • Auto-generated documentation comments
  • Simple, consistent "R" class name across all projects

Configuration

In your .csproj file:

<PropertyGroup>
    <!-- Enable/disable resource packing -->
    <ResourcePackerEnabled>true</ResourcePackerEnabled>
    
    <!-- Custom resource directory (default: Resources) -->
    <ResourcePackerDirectory>Resources</ResourcePackerDirectory>
    
    <!-- Custom output filename -->
    <ResourcePackerOutputFileName>$(AssemblyName).dat</ResourcePackerOutputFileName>
</PropertyGroup>

Compression

LuYao.ResourcePacker includes intelligent tiered compression to optimize package size while maintaining fast access:

Compression Strategy

Resources are automatically compressed using GZip based on these rules:

  1. Files < 255 bytes: Not compressed (overhead exceeds benefit)
  2. Files 255 bytes - 4KB: Full file compression attempted, only applied if compression ratio ≥ 5%
  3. Files > 4KB: First 8KB sampled for compression evaluation, full file compressed if sample ratio ≥ 5%
  4. Already compressed formats: Automatically skipped (jpg, png, zip, mp3, mp4, pdf, fonts, etc.)

Benefits

  • Automatic: No configuration needed - compression decisions made intelligently during build
  • Transparent: Decompression happens automatically when reading resources
  • Efficient: Typical 50-80% size reduction for compressible content (text, JSON, XML, source code)
  • Smart: Avoids compressing already-compressed formats and small files

Technical Details

  • Compression algorithm: GZip
  • Minimum compression ratio: 5%
  • Streaming decompression: Large compressed resources can be streamed without loading entire content into memory
  • Thread-safe: Concurrent access to compressed resources is fully supported

The compression is completely transparent to your code - no API changes required.

How the Source Generator Works

When you add resource files (e.g., test.txt, config.json) to your Resources directory:

  1. During build, the MSBuild task scans all files in the Resources directory
  2. These files are packaged into a .dat file
  3. The source generator creates an internal static class named R in the project's root namespace (defaults to assembly name) with:
    • A nested Keys class containing const strings for each resource (filename without extension)
    • A static Reader property providing access to the ResourcePackageReader
    • Strongly-typed methods like ReadTestAsync() and ReadConfigAsync()
  4. Resource keys are generated from filenames (without extension), with invalid C# identifier characters replaced by underscores

Example generated code:

namespace YourAssembly
{
    internal static class R
    {
        public static class Keys
        {
            public const string test = "test";
            public const string config = "config";
        }
        
        public static ResourcePackageReader Reader { get; }
        
        public static Task<byte[]> ReadTestAsync() { ... }
        public static Task<string> ReadTestAsStringAsync() { ... }
        
        public static Task<byte[]> ReadConfigAsync() { ... }
        public static Task<string> ReadConfigAsStringAsync() { ... }
    }
}

Building

dotnet build

Running Tests

dotnet test

License

This project is licensed under the MIT License - see the LICENSE file for details.

Created By

Created by Soar360 on 2025-10-25

About

A .NET library for packaging and accessing resource files during build time and runtime.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages