Bodu.IO.Compound 1.0.0

dotnet add package Bodu.IO.Compound --version 1.0.0
                    
NuGet\Install-Package Bodu.IO.Compound -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bodu.IO.Compound" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bodu.IO.Compound" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Bodu.IO.Compound" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Bodu.IO.Compound --version 1.0.0
                    
#r "nuget: Bodu.IO.Compound, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Bodu.IO.Compound@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Bodu.IO.Compound&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Bodu.IO.Compound&version=1.0.0
                    
Install as a Cake Tool

Bodu.IO.Compound

API stability — Stable. The public API surface is committed; breaking changes are reserved for a major-version bump per SemVer.

A small, dependency-free reader, editor, and writer for the OLE2 / Compound File Binary (CFB) container format — the structured-storage envelope behind legacy Microsoft Office files such as .xls, .doc, .ppt, and .msg.

It understands the container: it navigates the storage hierarchy, exposes the metadata of every entry, materializes the bytes of any named stream, edits existing containers transactionally, authors new ones, and reads and writes OLE property sets (summary information). It applies no interpretation to application stream contents — turning those bytes into a workbook, a document, or anything else is the consumer's job.

using Bodu.IO.Compound;

using var file = CompoundFile.Open(stream);

// Navigate the storage hierarchy (the IStorage / IStream model).
foreach (CompoundEntryInfo entry in file.RootStorage.EnumerateEntries())
    Console.WriteLine($"{entry.Name} ({entry.EntryType}, {entry.Length} bytes, clsid {entry.ClassId})");

if (file.RootStorage.TryOpenStream("Workbook", out CompoundStream? workbook))
{
    using (workbook)
        ProcessWorkbook(workbook.ReadAllBytes()); // or use workbook as a Stream
}

// Read document metadata from the OLE property sets.
if (file.TryGetSummaryInformation(out var summary))
    Console.WriteLine($"{summary.Title} by {summary.Author}, created {summary.CreateTime}");

Capabilities

  • Header, sector-size, and signature validation; CompoundFile.IsCompoundFile for a non-destructive signature probe.
  • Open from a Stream (CompoundFile.Open) or a path (CompoundFile.OpenRead(path)), with span- and async-capable per-stream reads (CompoundStream.Read(Span<byte>) / ReadAsync).
  • Regular FAT traversal (including extended DIFAT sectors) and mini-FAT / mini-stream resolution, with cycle and out-of-range detection.
  • A navigable storage hierarchy (CompoundStorage / CompoundStream) with child lookups scoped per storage — the managed counterpart of COM IStorage / IStream. CompoundFile.Open / CompoundStorage.OpenStream accept BCL FileMode / FileAccess, mirroring System.IO.Packaging.
  • A unified, package-aligned write API: CompoundFile.Create(stream) / Create(path) starts a new file, and CompoundFile.Open(stream, FileMode.Open, FileAccess.ReadWrite) loads an existing one for update. The writable RootStorage exposes CreateStorage / CreateStream / Delete / Rename, a writable CompoundStream (payloads up to int.MaxValue; larger streams go through the deferred builder sources), and settable entry metadata (ClassId / CreationTime / ModifiedTime / StateBits) on a storage. Edits are staged in memory and written to the destination only when Commit() — or the asynchronous CommitAsync / FlushAsync — is called; Revert() discards them and disposing without committing leaves the destination untouched.
  • Bounded-memory streaming reads: CompoundFile.Open(stream, buffered: false) reads sectors on demand from a seekable stream, and CompoundStorage.OpenStream(name) returns a lazy CompoundStream for large streams, so a multi-gigabyte file can be read without buffering it whole. CompoundStorageBuilder.FromFile(file, lazy: true) reads into deferred nodes for a fully streamed read → re-save copy.
  • Tunable open behavior via CompoundFileOptions (CompoundFile.Open(stream, options)): a CompoundReadStrategy (Buffered / Streaming / Auto with a MaxBufferedBytes threshold) and a CompoundValidationLevel — Strict rejects malformed directory entries the default tolerates, the default Compatible matches the historical behavior, and Minimal recovers from cyclic / out-of-range / short sector chains by returning the bytes read so far.
  • Per-entry metadata via CompoundEntryInfo (the STATSTG analogue): class id, state bits, creation / modified time stamps, and red-black node color — readable on any entry and settable on a writable storage (see the write API above). CompoundStream.Parent / CompoundStorage.Parent give upward navigation, and every exception derives from CompoundFileException.
  • OLE property-set parsing and writing (Bodu.IO.Compound.PropertySets): OlePropertySet / OlePropertyValue (PROPVARIANT, including vector values) plus the strongly-typed SummaryInformation / DocumentSummaryInformation views and …Builder authors, including user-defined custom properties. On a writable file, CompoundFile.SetSummaryInformation / SetDocumentSummaryInformation and CompoundStorage.WritePropertySet embed a set as the read counterparts of TryGet… / TryOpenPropertySet.
  • A detached snapshot-authoring model, CompoundStorageBuilder: build a JsonNode-style tree of CompoundStorageBuilder / CompoundStreamBuilder children with CompoundStorageBuilder.CreateRoot() (or CompoundStorageBuilder.Load an existing file into one), then WriteTo / Save / ToArray to a conforming container (v3 or v4). Output is verified byte-for-byte and cross-checked against the independent olefile and OpenMcdf parsers. (For live read/write use CompoundFile.)
  • Bounded-memory streaming writes: CompoundStorageBuilder.WriteTo(Stream) emits one sector at a time and large payloads can be sourced on demand via CompoundStreamBuilder.CreateFromFile(name, path) or Create(name, Func<Stream>, length) (and the matching CompoundStorageBuilder.AddStreamFromFile), so multi-gigabyte containers serialize without being buffered whole in memory.
  • Stable, message-independent failure classification through CompoundFileFormatException.Category (CompoundFileError) and a CompoundFileSerializationException for authoring errors.
using Bodu.IO.Compound;
using Bodu.IO.Compound.Builders;
using Bodu.IO.Compound.PropertySets;

var builder = CompoundStorageBuilder.CreateRoot();
builder.AddStorage("Storage 1").AddStream("Stream 1", new byte[] { 1, 2, 3 });
builder.AddStream(SummaryInformation.StreamName,
    new SummaryInformationBuilder { Title = "Report", Author = "Ada" }.ToArray());
builder.WriteTo(stream);   // writes an OLE2 / CFB file

Runnable samples

The repository ships an offline, dotnet run-able sample for this package — builder-based authoring with byte-exact read-back, OLE property sets on authored and real Word files, signature detection with the v3/v4 version knob, and walking a real .doc's storage tree — under samples/IO.Compound/.

Out of scope

Both creating and updating rebuild the whole container: Commit() serializes the entire staged tree and rewrites the destination from scratch. Incremental in-place editing that rewrites only the changed sectors of an existing file (the COM IStorage/Commit transacted model), encryption, and damaged-file recovery remain out of scope.

Part of the Bodu utility library.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Bodu.IO.Compound:

Package Downloads
Bodu.Formats.Excel.Binary

A narrow, read-only reader for the Excel binary workbook format (.xls): BIFF8 as written by Excel 97-2003 and BIFF5 as written by Excel 5.0/95. Exposes the raw cell values of a worksheet — strings, numbers, booleans, and errors, including the cached result of a formula cell — along with each cell's number format and date-format detection, the workbook date system, each sheet's declared used range, and the workbook document properties. Offers both a streaming cell surface and a materialized, randomly addressable worksheet view, without formula evaluation, styling, or any higher-level interpretation. Built on Bodu.IO.Compound for the container and Bodu.IO.Biff for the record stream.

Bodu.Formats.Outlook.Msg

A read-only reader for the Outlook message format (.msg / MS-OXMSG) over the Bodu.IO.Compound OLE2 container. Opens a message as a disposable session exposing every decoded MAPI property, the recipient and attachment tables, nested attached messages, named-property resolution, and the text, HTML, and compressed-RTF bodies — without any MAPI session emulation or message authoring. Shares the Bodu.Formats.Outlook MAPI value model.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 60 9/24/2026
0.7.0 116 9/24/2026
0.6.0 73 9/24/2026
0.5.0 75 9/23/2026