OpenMcdf is a 100% .NET / C# component that allows developers to manipulate Microsoft Compound Document File Format for OLE structured storage. It supports read/write operations on streams and storages and traversal of directory trees.
$ dotnet add package OpenMcdfOpenMcdf is a fully .NET / C# library to manipulate Compound File Binary File Format files, also known as Structured Storage.
Compound files include multiple streams of information (document summary, user data) in a single container, and is used as the bases for many different file formats:
OpenMcdf v3 has a rewritten API and supports:
Directory entries are stored in a perfect binary tree where the entries are sorted but the tree is not balanced. i.e. the tree is "all-black", which is a valid red-black tree but has suboptimal performance for traversing large trees (though still considerably faster than some other clients).
Clients such as LibreOffice create trees with red-violations, which OpenMcdf is tolerant to reading and writing. Files with balanced red-black trees such as those created by Microsoft implementations will currently become unbalanced upon adding or removing directory entries. Fortunately, since other clients are also tolerant of trees that are either unbalanced or have red-violations, this should not be a major issue. The Wine implementation also has the same limitation.
To create a new compound file:
byte[] b = new byte[10000];
using var root = RootStorage.Create("test.cfb");
using CfbStream stream = root.CreateStream("MyStream");
stream.Write(b, 0, b.Length);
To open an Excel workbook (.xls) and access its main data stream:
using var root = RootStorage.OpenRead("report.xls");
using CfbStream workbookStream = root.OpenStream("Workbook");
To create or delete storages and streams:
using var root = RootStorage.Create("test.cfb");
root.CreateStorage("MyStorage");
root.CreateStream("MyStream");
root.Delete("MyStream");
For transacted storages, changes can either be committed or reverted:
using var root = RootStorage.Create("test.cfb", StorageModeFlags.Transacted);
root.Commit();
//
root.Revert();
A root storage can be consolidated to reduce its on-disk size:
root.Flush(consolidate: true);
Support for reading and writing OLE Properties is available via the OpenMcdf.Ole package. However, the API is experimental and subject to change.
OlePropertiesContainer co = new(stream);
foreach (OleProperty prop in co.Properties)
{
...
}
OpenMcdf runs happily on the Mono platform and multi-targets netstandard2.0, net8.0, and net10.0 to maximize client compatibility and support modern dotnet features.