Skip to content

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: Attachments 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 Attachments directory:

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

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

Note: The default directory was changed from Resources to Attachments to avoid conflicts with C# .resx files, which typically use the Resources directory. If you prefer to use Resources or any other directory name, you can configure it in your .csproj file (see Configuration section below).

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: Attachments) -->
    <ResourcePackerDirectory>Attachments</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