dotnet add package RecursiveAI.OneArchiveRequires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneArchive; File.WriteAllText("hello.txt", "Hello!"); Archive.Create("hello.7z") .Add("hello.txt").Save(); Console.WriteLine("Wrote hello.7z");
Wrote hello.7zUnzip the example, then dotnet run.
The full program
The program generates its own input text: hello.txt contains Hello! and notes.txt contains Keep this file., each followed by a newline.
using RecursiveAI.OneArchive; File.WriteAllText("hello.txt", "Hello!\n"); File.WriteAllText("notes.txt", "Keep this file.\n"); Archive.Create("bundle.7z") .Add("hello.txt", "docs/hello.txt") .Add("notes.txt", "docs/notes.txt").Save(); Console.WriteLine("Wrote bundle.7z"); using var archive = Archive.Open("bundle.7z"); foreach (var entry in archive.Entries) { Console.WriteLine($"{entry.Name}: {entry.Size} bytes"); using var content = archive.OpenEntry(entry); using var text = new StreamReader(content); Console.Write(text.ReadToEnd()); }
dotnet run prints:
Wrote bundle.7z docs/hello.txt: 7 bytes Hello! docs/notes.txt: 16 bytes Keep this file.
Missing source paths raise FileNotFoundException; a source whose size changes before Save finishes is rejected.
Variations
Choose LZMA2 and separate compression streams
This standalone variation turns off solid compression, so files do not share a compression stream.
using RecursiveAI.OneArchive; using RecursiveAI.OneArchive.SevenZip; File.WriteAllText("hello.txt", "Hello!"); var options = new ArchiveCreateOptions { SevenZip = new SevenZipWriterOptions { Method = SevenZipMethod.Lzma2, Level = 3, Solid = false } }; Archive.Create("separate.7z", options) .Add("hello.txt").Save(); Console.WriteLine("Wrote separate.7z");
Wrote separate.7zRelated recipes
The short answer
Use Archive.Create("bundle.7z"), add each source file, then call Save(). The extension selects the 7z writer. The snippet at the top creates its own input, so you can paste it into a new console project after installing the package. It does not invoke a command-line program or require native binaries.
The complete example adds two generated text files under docs/ and opens the result again. The listing shows uncompressed byte counts, followed by the actual text read from each entry.
How do I create a 7z archive from multiple files in C#?
Chain Add calls before Save, as the full program does. The first argument is the source path on disk. The optional second argument is the name inside the archive. Add("hello.txt", "docs/hello.txt") puts the file under docs/ without moving the original file.
Entries are written in the order you add them. Adding a directory adds its own entry and then its contents; children within each directory are sorted by ordinal name. If you want a particular file order, add the files explicitly in that order. The archive builder reads file contents when Save runs, not when you call Add, and rejects a file whose size has changed since it was added.
Keep the archive name outside any input directory you are collecting. Use / for archive path separators. The archive builder documentation describes the file, directory and in-memory entry overloads.
How do I choose 7z compression options in C#?
Pass ArchiveCreateOptions to Archive.Create, with a SevenZipWriterOptions value in its SevenZip property. The variation above selects LZMA2 at level 3 and sets Solid = false. The defaults are LZMA2, level 5 and solid compression: multiple files can share one compression stream. Non-solid output starts a separate stream for each file that has content.
Level 0 means Copy, regardless of the chosen method: it stores content without compression. Levels 1 through 9 select the documented encoder configurations. A shared CompressionLevel setting overrides the nested Level, so avoid setting both unless that override is intentional. These settings change encoding choices, not file names or contents. See the 7z writer options for dictionary overrides, block boundaries and filters.
A seekable output is written in place. For a non-seekable output, the writer builds the whole archive in memory and copies it out when finished; that path is limited to 2 GiB. Prefer a file output when you do not want whole-archive buffering. Hard links, devices and FIFOs cannot be written by the 7z writer and raise ArchiveUnsupportedException.