# luyao-resource-packer
**Repository Path**: coderbusy/luyao-resource-packer
## Basic Information
- **Project Name**: luyao-resource-packer
- **Description**: A .NET library for packaging and accessing resource files during build time and runtime.
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 1
- **Created**: 2025-10-28
- **Last Updated**: 2025-10-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# LuYao.ResourcePacker
[](https://www.nuget.org/packages/LuYao.ResourcePacker/)
[](https://www.nuget.org/packages/LuYao.ResourcePacker/)
[](https://github.com/coderbusy/luyao-resource-packer/stargazers)
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
```bash
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`:
```csharp
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:
```csharp
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:
```xml
true
Resources
$(AssemblyName).dat
```
## 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:
```csharp
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 ReadTestAsync() { ... }
public static Task ReadTestAsStringAsync() { ... }
public static Task ReadConfigAsync() { ... }
public static Task ReadConfigAsStringAsync() { ... }
}
}
```
## Building
```bash
dotnet build
```
## Running Tests
```bash
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