From 9649b47887b2b8d0b36eee0be490d094dfdbf8ea Mon Sep 17 00:00:00 2001 From: manusoft Date: Mon, 25 May 2026 18:27:22 +0400 Subject: [PATCH 1/3] Update UI app version and dependecies. --- app/FiloExplorer/FiloExplorer.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/FiloExplorer/FiloExplorer.csproj b/app/FiloExplorer/FiloExplorer.csproj index 1acf605..3f0b557 100644 --- a/app/FiloExplorer/FiloExplorer.csproj +++ b/app/FiloExplorer/FiloExplorer.csproj @@ -45,10 +45,12 @@ - + + + MSBuild:Compile From 2b9217f3789736258a56e4d2f88da014585cfd3b Mon Sep 17 00:00:00 2001 From: manusoft Date: Mon, 25 May 2026 18:27:40 +0400 Subject: [PATCH 2/3] Update console app codes. --- test/Filo.Console/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Filo.Console/Program.cs b/test/Filo.Console/Program.cs index 2134ade..1939d0c 100644 --- a/test/Filo.Console/Program.cs +++ b/test/Filo.Console/Program.cs @@ -1,7 +1,7 @@ ο»Ώusing ManuHub.Filo; using System.Security.Cryptography; -string filoPath = "backupv1.1.filo"; +string filoPath = "backupv1.2.filo"; try { @@ -30,7 +30,7 @@ try { Console.WriteLine("Read file header:"); - var header = await FiloReader.ReadHeaderAsync("backupv1.1.filo"); + var header = await FiloReader.ReadHeaderAsync("backupv1.2.filo"); Console.WriteLine($"Files: {header.FileCount}"); Console.WriteLine($"Created: {header.Created}"); From 3cf383c824119aa5cc5db1d42d289e6112208df9 Mon Sep 17 00:00:00 2001 From: manusoft Date: Mon, 25 May 2026 18:28:10 +0400 Subject: [PATCH 3/3] FILO v1.2: deterministic footer, stricter validation Update container format to v1.2.0 with a fixed 28-byte footer and "FLOF" magic for corruption detection. Add strict offset and length validation in FiloReader. Standardize chunk format and clarify offset rules in FiloChunkIndex. Update constants and introduce FiloFooter for footer size. Revise README with new format, usage, and integrity/security details. Bump project version to 1.2.0. --- README.md | 237 +++++++++++++++++------------ src/Filo/Core/FiloReader.cs | 44 +++++- src/Filo/Filo.csproj | 4 +- src/Filo/Models/FiloChunkIndex.cs | 24 +++ src/Filo/README.md | 242 ++++++++++++++++++------------ src/Filo/Shared/FiloConstants.cs | 6 + 6 files changed, 362 insertions(+), 195 deletions(-) diff --git a/README.md b/README.md index dbad085..796fdd4 100644 --- a/README.md +++ b/README.md @@ -7,85 +7,93 @@ FILO -## FILO v1.1 Highlights +--- -**Added:** +## FILO v1.2.0 Highlights -* βœ” Chunk integrity hashing (SHA256) -* βœ” Password-based encryption (PBKDF2) +### 🧱 Stability & Format Fixes +- βœ” Fixed footer structure (v1.2 deterministic format) +- βœ” Standardized chunk format (encrypted + plain) +- βœ” Fixed index offset validation issues +- βœ” Added footer magic validation (`FLOF`) +- βœ” Stronger container corruption detection -**Deprecated:** +### πŸ” Security Improvements +- βœ” Password-based encryption (PBKDF2 + AES) +- βœ” Encryption contract stabilized (AES-CBC defined) +- βœ” Password verification via SHA256 check +- βœ” Safer chunk validation during streaming -* ⚠ `WithEncryption(byte[] key)` β€” use `WithPassword(string password)` instead. +### βš™οΈ Reliability Improvements +- βœ” Safe offset & length validation +- βœ” Stronger reader error handling +- βœ” Deterministic file structure --- ## Overview -**FILO** (Files In, Layered & Organized) is a modern **multi-file container format** for .NET designed for **large files**. -It stores multiple files (video, audio, text, binaries, etc.) in a **single container**, supporting: +**FILO** (Files In, Layered & Organized) is a modern multi-file container format for .NET designed for large-scale file storage and streaming. + +It supports: -* **Large files** (GB-sized videos, audio, binaries) -* **Multiple files per container** -* **Chunked streaming** for memory-efficient reads -* **AES256 optional encryption per chunk** -* **Embedded metadata** -* **File checksums** for integrity -* Fully **async APIs** +- Large files (GB-sized video/audio/binaries) +- Multi-file containers +- Chunked streaming (memory efficient) +- Optional AES256 encryption per chunk +- Embedded metadata & integrity checks +- Fully async APIs -> FILO = **Files In, Layered & Organized** β€” ideal for **video/audio streaming, backups, and custom file packaging**. +> FILO is designed for **streaming-first storage systems**, not just archive compression. --- ## Why FILO? -Traditional ZIP or JSON-based storage has limitations: +Traditional formats like ZIP have limitations: -- Limited streaming support for large files -- No native chunked encryption -- Metadata is often scattered or external +- ❌ Poor streaming support +- ❌ Weak chunk-level control +- ❌ No streaming encryption model +- ❌ Limited metadata structure -**FILO solves this** by: +FILO solves this by: -- Storing files in **chunks** for streaming or partial reads -- Supporting **encryption at chunk level** -- Embedding **metadata and checksums** -- Providing **simple async APIs** in fluent style +- Streaming files in **chunks** +- Encrypting **per chunk** +- Embedding **structured metadata** +- Supporting **direct streaming without extraction** --- -## FILO Container Layout +## FILO Container Layout (v1.2) ```text +------------------------------------------------+ -| Header (JSON) | -| - Format: "FILO" | -| - Version | -| - Created (UTC) | -| - ChunkSize | -| - FileCount | -| - Compression | -| - Encryption | -| - Description | +| HEADER (JSON) | +|------------------------------------------------| +| - Format: FILO | +| - Version: 1.2 | +| - ChunkSize | +| - FileCount | +| - Encryption Mode (AES-CBC) | +| - KDF (PBKDF2) | +------------------------------------------------+ -| File Chunks | -| [chunk1] [chunk2] ... | -| (Encrypted if AES256) | +| FILE CHUNKS | +| [IV][LEN][DATA] (encrypted) | +| [LEN][DATA] (plain) | +------------------------------------------------+ -| Index (JSON) | -| - File names | -| - Offsets | -| - Chunk sizes | +| INDEX (JSON) | +------------------------------------------------+ -| Metadata (JSON) | -| - File metadata (MIME type, tags, etc.) | +| METADATA (JSON) | +------------------------------------------------+ -| Checksum (JSON) | -| - SHA256 hashes | +| CHECKSUM (JSON) | +------------------------------------------------+ -| Footer | -| - Index offset | -| - Metadata offset | +| FOOTER | +| - IndexOffset | +| - MetadataOffset | +| - ChecksumOffset | +| - "FLOF" magic | +------------------------------------------------+ ``` > This design allows **streaming large files directly**, without full extraction. @@ -108,85 +116,101 @@ Traditional ZIP or JSON-based storage has limitations: --- - ## Installation Install via NuGet: ```bash -dotnet add package Filo --version 1.1.0 +dotnet add package Filo --version 1.2.0 ```` --- ## Basic Usage -### Writing a container +### πŸ“¦ Create Container ```csharp using Filo; -var pwd = "mypassword"; - var writer = new FiloWriter("backup.filo") .AddFile("video.mp4", new FileMetadata { MimeType = "video/mp4" }) - .AddFile("subtitle.srt", new FileMetadata { MimeType = "text/plain" }) + .AddFile("audio.mp3", new FileMetadata { MimeType = "audio/mpeg" }) .WithChunkSize(5_000_000) - .WithPassword(pwd); + .WithPassword("1234567890"); await writer.WriteAsync(); + Console.WriteLine("FILO container created!"); ``` -### Reading files +### πŸ“– Read Container ```csharp var reader = new FiloReader("backup.filo"); await reader.InitializeAsync(); -var key = reader.DeriveKey("mypassword"); +var key = reader.DeriveKey("1234567890"); -// List files foreach (var file in reader.ListFiles()) - Console.WriteLine(file); - -// Stream chunks -await foreach (var chunk in reader.StreamFileAsync("video.mp4", key)) { - await chunk.WriteAsync(chunk); + Console.WriteLine($"{file.Name} ({file.FileSize} bytes)"); } ``` --- - -### Direct Streaming +### πŸ“‘ Stream File (Recommended) ```csharp -using var stream = reader.OpenStream("video.mp4", key); -await stream.CopyToAsync(outputFile); +await using var stream = reader.OpenStream("video.mp4", key); +await using var output = File.Create("restored.mp4"); + +await stream.CopyToAsync(output); ``` -### Extract Files Using `FiloStream` +--- -```csharp -using var filoStream = new FiloStream(reader, "video.mp4", key); -using var output = File.Create("video_restored.mp4"); +### πŸ” Chunk-by-chunk processing -await filoStream.CopyToAsync(output); -Console.WriteLine("File extracted!"); +```csharp +await foreach (var chunk in reader.StreamFileAsync("video.mp4", key)) +{ + // Process streaming data +} ``` -### Load Image +--- -```csharp -using var stream = new FiloStream(reader, "photo.jpg"); -using var image = System.Drawing.Image.FromStream(stream); +### πŸ” Encryption Model (v1.2) -Console.WriteLine($"Loaded image: {image.Width}x{image.Height}"); +- Encrypted chunk format: + ``` + [16-byte IV][4-byte length][encrypted data] + ``` +- Plain chunk format: + ``` + [4-byte length][plain data] + ``` -``` +* Key derived using PBKDF2 (100k iterations) +* AES-CBC encryption per chunk +* Password verification via SHA256 key hash + +--- + +### 🧠 Integrity System + +- Each chunk is validated using SHA256: + ```csharp + var checksum = await FiloChecksum.ComputeFileSHA256Async("video.mp4"); + ``` + +* Prevents corrupted chunk playback +* Ensures file integrity during streaming + +--- -## Streaming Video/Audio in ASP.NET Core / Blazor +### 🌐 ASP.NET Streaming Example ```csharp public async Task GetVideo() @@ -195,6 +219,7 @@ public async Task GetVideo() await reader.InitializeAsync(); var key = reader.DeriveKey("password"); + var stream = new FiloStream(reader, "movie.mp4", key); return File(stream, "video/mp4"); @@ -238,17 +263,29 @@ await foreach (var chunk in reader.StreamFileAsync("largevideo.mp4", key)) --- -## ⚑ When to Use FiloStream vs StreamFileAsync +## ⚑ When to Use What + +| Method | Use Case | +| ------------------- | ----------------------- | +| `OpenStream()` | Direct file streaming | +| `FiloStream` | ASP.NET / UI streaming | +| `StreamFileAsync()` | Custom chunk processing | +| `CopyToAsync()` | Extraction | -| Method | Best For | -| ------------------| ---------------- | -| StreamFileAsync() | chunk processing | -| FiloStream normal | file streaming | -| CopyToAsync() | extraction | -| HTTP streaming | media servers | --- +### πŸ“¦ File Metadata + +```csharp +new FileMetadata +{ + MimeType = "video/mp4", + Description = "Main movie file" +} +``` +--- + > Always verify checksum for **large file integrity**. @@ -275,11 +312,26 @@ Console.WriteLine(checksum); --- -## Notes +## πŸ”§ Core Classes + +| Class | Responsibility | +| -------------- | ---------------------- | +| FiloWriter | Builds container | +| FiloReader | Reads container | +| FiloStream | Streaming abstraction | +| FiloChecksum | Integrity verification | +| FiloEncryption | AES operations | + +--- + -* FILO supports **any file type**: video, audio, images, text, binaries -* For **large containers (GBs)**, keep them **server-side** and stream with `FiloStream`. -* Fully **async and memory-efficient** +## Notes (v1.2 Rules) + +* Footer size is fixed (28 bytes) +* Chunk offsets always point to chunk start +* AES-CBC is the defined encryption mode +* Index must always validate against file length +* Footer magic must be "FLOF" --- @@ -288,4 +340,3 @@ Console.WriteLine(checksum); MIT License - diff --git a/src/Filo/Core/FiloReader.cs b/src/Filo/Core/FiloReader.cs index 75caaf1..be3aa28 100644 --- a/src/Filo/Core/FiloReader.cs +++ b/src/Filo/Core/FiloReader.cs @@ -1,4 +1,5 @@ -ο»Ώusing ManuHub.Filo.Utils; +ο»Ώusing ManuHub.Filo.Shared; +using ManuHub.Filo.Utils; using System.Security.Cryptography; using System.Text; using System.Text.Json; @@ -67,19 +68,37 @@ public async Task InitializeAsync() ?? throw new InvalidDataException("Failed to deserialize header."); // FOOTER - fs.Seek(-16, SeekOrigin.End); + fs.Seek(-FiloFooter.Size, SeekOrigin.End); var longBuffer = new byte[8]; + // INDEX OFFSET await fs.ReadExactlyAsync(longBuffer); long indexOffset = BitConverter.ToInt64(longBuffer); + // METADATA OFFSET await fs.ReadExactlyAsync(longBuffer); long metadataOffset = BitConverter.ToInt64(longBuffer); - if (indexOffset >= fs.Length) + // CHECKSUM OFFSET + await fs.ReadExactlyAsync(longBuffer); + long checksumOffset = BitConverter.ToInt64(longBuffer); + + // FOOTER MAGIC + var magicBuf = new byte[4]; + await fs.ReadExactlyAsync(magicBuf); + + var footerMagic = Encoding.ASCII.GetString(magicBuf); + + if (footerMagic != "FLOF") + throw new InvalidDataException("Invalid FILO footer."); + + if (indexOffset <= 0 || indexOffset >= fs.Length) throw new InvalidDataException("Invalid index offset."); + if (metadataOffset < 0 || metadataOffset >= fs.Length) + throw new InvalidDataException("Invalid metadata offset."); + // READ INDEX fs.Position = indexOffset; @@ -210,6 +229,12 @@ public async IAsyncEnumerable StreamFileAsync(string fileName, byte[]? k { fs.Position = chunk.Offset; + if (chunk.Offset < 0 || chunk.Offset >= fs.Length) + { + throw new InvalidDataException( + $"Chunk {chunk.Id} has invalid offset: {chunk.Offset}"); + } + byte[] dataChunk; try @@ -223,6 +248,12 @@ public async IAsyncEnumerable StreamFileAsync(string fileName, byte[]? k await fs.ReadExactlyAsync(lenBuf); int len = BitConverter.ToInt32(lenBuf); + if (len <= 0 || len > fs.Length) + { + throw new InvalidDataException( + $"Invalid encrypted chunk length: {len}"); + } + var enc = new byte[len]; await fs.ReadExactlyAsync(enc); @@ -232,9 +263,14 @@ public async IAsyncEnumerable StreamFileAsync(string fileName, byte[]? k { var lenBuf = new byte[4]; await fs.ReadExactlyAsync(lenBuf); - int len = BitConverter.ToInt32(lenBuf); + if (len <= 0 || len > fs.Length) + { + throw new InvalidDataException( + $"Invalid chunk length: {len}"); + } + dataChunk = new byte[len]; await fs.ReadExactlyAsync(dataChunk); } diff --git a/src/Filo/Filo.csproj b/src/Filo/Filo.csproj index c842049..ac059e6 100644 --- a/src/Filo/Filo.csproj +++ b/src/Filo/Filo.csproj @@ -6,10 +6,10 @@ enable latest Filo - 1.1.0 + 1.2.0 ManuHub.Filo Filo - 1.1.0 + 1.2.0 Manojbabu ManuHub FILO – Fast, flexible multi-file container for .NET with streaming, encryption, and metadata support. diff --git a/src/Filo/Models/FiloChunkIndex.cs b/src/Filo/Models/FiloChunkIndex.cs index 51239d1..aaab65f 100644 --- a/src/Filo/Models/FiloChunkIndex.cs +++ b/src/Filo/Models/FiloChunkIndex.cs @@ -2,8 +2,32 @@ public class FiloChunkIndex { + /// + /// Chunk identifier (sequential per file) + /// public int Id { get; set; } + + /// + /// File offset where this chunk starts. + /// + /// IMPORTANT (v1.2 RULE): + /// Offset always points to the beginning of the chunk header: + /// + /// If encrypted: + /// [IV (16 bytes)][Length (4 bytes)][Data] + /// + /// If not encrypted: + /// [Length (4 bytes)][Data] + /// public long Offset { get; set; } + + /// + /// Total stored chunk size in container (header + data) + /// public int Length { get; set; } + + /// + /// SHA256 hash of ORIGINAL (decrypted) chunk data + /// public string? Hash { get; set; } // v1.1 } \ No newline at end of file diff --git a/src/Filo/README.md b/src/Filo/README.md index 3279500..2069769 100644 --- a/src/Filo/README.md +++ b/src/Filo/README.md @@ -6,85 +6,91 @@ --- -## FILO v1.1 Highlights - -**Added:** - -* βœ” Chunk integrity hashing (SHA256) -* βœ” Password-based encryption (PBKDF2) - -**Deprecated:** - -* ⚠ `WithEncryption(byte[] key)` β€” use `WithPassword(string password)` instead. +## FILO v1.2.0 Highlights + +### 🧱 Stability & Format Fixes +- βœ” Fixed footer structure (v1.2 deterministic format) +- βœ” Standardized chunk format (encrypted + plain) +- βœ” Fixed index offset validation issues +- βœ” Added footer magic validation (`FLOF`) +- βœ” Stronger container corruption detection + +### πŸ” Security Improvements +- βœ” Password-based encryption (PBKDF2 + AES) +- βœ” Encryption contract stabilized (AES-CBC defined) +- βœ” Password verification via SHA256 check +- βœ” Safer chunk validation during streaming + +### βš™οΈ Reliability Improvements +- βœ” Safe offset & length validation +- βœ” Stronger reader error handling +- βœ” Deterministic file structure --- ## Overview -**FILO** (Files In, Layered & Organized) is a modern **multi-file container format** for .NET designed for **large files**. -It stores multiple files (video, audio, text, binaries, etc.) in a **single container**, supporting: +**FILO** (Files In, Layered & Organized) is a modern multi-file container format for .NET designed for large-scale file storage and streaming. + +It supports: -* **Large files** (GB-sized videos, audio, binaries) -* **Multiple files per container** -* **Chunked streaming** for memory-efficient reads -* **AES256 optional encryption per chunk** -* **Embedded metadata** -* **File checksums** for integrity -* Fully **async APIs** +- Large files (GB-sized video/audio/binaries) +- Multi-file containers +- Chunked streaming (memory efficient) +- Optional AES256 encryption per chunk +- Embedded metadata & integrity checks +- Fully async APIs -> FILO = **Files In, Layered & Organized** β€” ideal for **video/audio streaming, backups, and custom file packaging**. +> FILO is designed for **streaming-first storage systems**, not just archive compression. --- ## Why FILO? -Traditional ZIP or JSON-based storage has limitations: +Traditional formats like ZIP have limitations: -- Limited streaming support for large files -- No native chunked encryption -- Metadata is often scattered or external +- ❌ Poor streaming support +- ❌ Weak chunk-level control +- ❌ No streaming encryption model +- ❌ Limited metadata structure -**FILO solves this** by: +FILO solves this by: -- Storing files in **chunks** for streaming or partial reads -- Supporting **encryption at chunk level** -- Embedding **metadata and checksums** -- Providing **simple async APIs** in fluent style +- Streaming files in **chunks** +- Encrypting **per chunk** +- Embedding **structured metadata** +- Supporting **direct streaming without extraction** --- -## FILO Container Layout +## FILO Container Layout (v1.2) ```text +------------------------------------------------+ -| Header (JSON) | -| - Format: "FILO" | -| - Version | -| - Created (UTC) | -| - ChunkSize | -| - FileCount | -| - Compression | -| - Encryption | -| - Description | +| HEADER (JSON) | +|------------------------------------------------| +| - Format: FILO | +| - Version: 1.2 | +| - ChunkSize | +| - FileCount | +| - Encryption Mode (AES-CBC) | +| - KDF (PBKDF2) | +------------------------------------------------+ -| File Chunks | -| [chunk1] [chunk2] ... | -| (Encrypted if AES256) | +| FILE CHUNKS | +| [IV][LEN][DATA] (encrypted) | +| [LEN][DATA] (plain) | +------------------------------------------------+ -| Index (JSON) | -| - File names | -| - Offsets | -| - Chunk sizes | +| INDEX (JSON) | +------------------------------------------------+ -| Metadata (JSON) | -| - File metadata (MIME type, tags, etc.) | +| METADATA (JSON) | +------------------------------------------------+ -| Checksum (JSON) | -| - SHA256 hashes | +| CHECKSUM (JSON) | +------------------------------------------------+ -| Footer | -| - Index offset | -| - Metadata offset | +| FOOTER | +| - IndexOffset | +| - MetadataOffset | +| - ChecksumOffset | +| - "FLOF" magic | +------------------------------------------------+ ``` > This design allows **streaming large files directly**, without full extraction. @@ -107,85 +113,101 @@ Traditional ZIP or JSON-based storage has limitations: --- - ## Installation Install via NuGet: ```bash -dotnet add package Filo --version 1.1.0 +dotnet add package Filo --version 1.2.0 ```` --- ## Basic Usage -### Writing a container +### πŸ“¦ Create Container ```csharp using Filo; -var pwd = "mypassword"; - var writer = new FiloWriter("backup.filo") .AddFile("video.mp4", new FileMetadata { MimeType = "video/mp4" }) - .AddFile("subtitle.srt", new FileMetadata { MimeType = "text/plain" }) + .AddFile("audio.mp3", new FileMetadata { MimeType = "audio/mpeg" }) .WithChunkSize(5_000_000) - .WithPassword(pwd); + .WithPassword("1234567890"); await writer.WriteAsync(); + Console.WriteLine("FILO container created!"); ``` -### Reading files +### πŸ“– Read Container ```csharp var reader = new FiloReader("backup.filo"); await reader.InitializeAsync(); -var key = reader.DeriveKey("mypassword"); +var key = reader.DeriveKey("1234567890"); -// List files foreach (var file in reader.ListFiles()) - Console.WriteLine(file); - -// Stream chunks -await foreach (var chunk in reader.StreamFileAsync("video.mp4", key)) { - await chunk.WriteAsync(chunk); + Console.WriteLine($"{file.Name} ({file.FileSize} bytes)"); } ``` --- - -### Direct Streaming +### πŸ“‘ Stream File (Recommended) ```csharp -using var stream = reader.OpenStream("video.mp4", key); -await stream.CopyToAsync(outputFile); +await using var stream = reader.OpenStream("video.mp4", key); +await using var output = File.Create("restored.mp4"); + +await stream.CopyToAsync(output); ``` -### Extract Files Using `FiloStream` +--- -```csharp -using var filoStream = new FiloStream(reader, "video.mp4", key); -using var output = File.Create("video_restored.mp4"); +### πŸ” Chunk-by-chunk processing -await filoStream.CopyToAsync(output); -Console.WriteLine("File extracted!"); +```csharp +await foreach (var chunk in reader.StreamFileAsync("video.mp4", key)) +{ + // Process streaming data +} ``` -### Load Image +--- -```csharp -using var stream = new FiloStream(reader, "photo.jpg"); -using var image = System.Drawing.Image.FromStream(stream); +### πŸ” Encryption Model (v1.2) -Console.WriteLine($"Loaded image: {image.Width}x{image.Height}"); +- Encrypted chunk format: + ``` + [16-byte IV][4-byte length][encrypted data] + ``` +- Plain chunk format: + ``` + [4-byte length][plain data] + ``` -``` +* Key derived using PBKDF2 (100k iterations) +* AES-CBC encryption per chunk +* Password verification via SHA256 key hash + +--- -## Streaming Video/Audio in ASP.NET Core / Blazor +### 🧠 Integrity System + +- Each chunk is validated using SHA256: + ```csharp + var checksum = await FiloChecksum.ComputeFileSHA256Async("video.mp4"); + ``` + +* Prevents corrupted chunk playback +* Ensures file integrity during streaming + +--- + +### 🌐 ASP.NET Streaming Example ```csharp public async Task GetVideo() @@ -194,6 +216,7 @@ public async Task GetVideo() await reader.InitializeAsync(); var key = reader.DeriveKey("password"); + var stream = new FiloStream(reader, "movie.mp4", key); return File(stream, "video/mp4"); @@ -237,15 +260,27 @@ await foreach (var chunk in reader.StreamFileAsync("largevideo.mp4", key)) --- -## ⚑ When to Use FiloStream vs StreamFileAsync +## ⚑ When to Use What + +| Method | Use Case | +| ------------------- | ----------------------- | +| `OpenStream()` | Direct file streaming | +| `FiloStream` | ASP.NET / UI streaming | +| `StreamFileAsync()` | Custom chunk processing | +| `CopyToAsync()` | Extraction | + -| Method | Best For | -| ------------------| ---------------- | -| StreamFileAsync() | chunk processing | -| FiloStream normal | file streaming | -| CopyToAsync() | extraction | -| HTTP streaming | media servers | +--- + +### πŸ“¦ File Metadata +```csharp +new FileMetadata +{ + MimeType = "video/mp4", + Description = "Main movie file" +} +``` --- > Always verify checksum for **large file integrity**. @@ -274,11 +309,26 @@ Console.WriteLine(checksum); --- -## Notes +## πŸ”§ Core Classes + +| Class | Responsibility | +| -------------- | ---------------------- | +| FiloWriter | Builds container | +| FiloReader | Reads container | +| FiloStream | Streaming abstraction | +| FiloChecksum | Integrity verification | +| FiloEncryption | AES operations | + +--- + + +## Notes (v1.2 Rules) -* FILO supports **any file type**: video, audio, images, text, binaries -* For **large containers (GBs)**, keep them **server-side** and stream with `FiloStream`. -* Fully **async and memory-efficient** +* Footer size is fixed (28 bytes) +* Chunk offsets always point to chunk start +* AES-CBC is the defined encryption mode +* Index must always validate against file length +* Footer magic must be "FLOF" --- diff --git a/src/Filo/Shared/FiloConstants.cs b/src/Filo/Shared/FiloConstants.cs index 09ae3e6..f6624d2 100644 --- a/src/Filo/Shared/FiloConstants.cs +++ b/src/Filo/Shared/FiloConstants.cs @@ -6,4 +6,10 @@ public static class FiloConstants public const int IvSize = 16; public const int LengthSize = 4; +} + +public static class FiloFooter +{ + public const int Size = + sizeof(long) + sizeof(long) + sizeof(long) + 4; } \ No newline at end of file