Skip to content

Add 7z archive writer with LZMA/LZMA2 compression#1229

Merged
adamhathcock merged 14 commits intoadamhathcock:masterfrom
DanNsk:feature/sevenzip-writer-lzma2-new
Feb 24, 2026
Merged

Add 7z archive writer with LZMA/LZMA2 compression#1229
adamhathcock merged 14 commits intoadamhathcock:masterfrom
DanNsk:feature/sevenzip-writer-lzma2-new

Conversation

@DanNsk
Copy link
Contributor

@DanNsk DanNsk commented Feb 23, 2026

Summary

Adds write support for 7z archives. Files can be compressed with LZMA or LZMA2 (default). Each file is compressed independently (non-solid mode). Archives produced pass 7z t validation and open correctly in 7-Zip GUI.

The writer plugs into the existing WriterFactory/SevenZipFactory infrastructure and supports both sync and async APIs. SevenZipWriterOptions controls compression type, header compression, and LZMA encoder settings.

Also adds LZMA2 to the CompressionType enum and a Lzma2EncoderStream that implements chunk-based LZMA2 framing on top of the existing LZMA encoder.

What's not included (but will/can add what i can if this PR will be accepted)

  • Solid mode (all files in one compression block)
  • Encryption
  • IWritableArchive integration
  • BCJ/BCJ2 filters
  • Truly async compression - LZMA is inherently CPU-bound and the underlying encoder is synchronous, so the async writer methods delegate to sync internally. Don't see a good way to make this genuinely async without Task.Run in library code, which just hides threading from the caller. Open to ideas if there's a better approach.

Testing

Round-trip tests cover single/multiple files, directories, empty files, large data, both compression methods, compressed and uncompressed headers, and factory-based creation. Tests pass on net10.0 and net48. Archives also verified externally with 7-Zip.

@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Feb 23, 2026

Code Review Summary

Status: 1 Active Issue | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs 97 Empty non-seekable streams can leave orphaned packed data - FIX IN PROGRESS (rewind added, awaiting final verification)

Note: The issue has been partially addressed with a rewind fix at lines 106-107 that erases orphaned encoder bytes when empty streams are detected. The author indicated they will extend this with byte probe later.

Files Reviewed (14 files)
  • src/SharpCompress/Common/CompressionType.cs - Added LZMA2 enum value
  • src/SharpCompress/Common/SevenZip/ArchiveWriter.cs - New header writer
  • src/SharpCompress/Common/SevenZip/SevenZipFilesInfo.cs - New files info writer
  • src/SharpCompress/Common/SevenZip/SevenZipHeaderStructures.cs - New header structures
  • src/SharpCompress/Common/SevenZip/SevenZipSignatureHeaderWriter.cs - New signature header
  • src/SharpCompress/Common/SevenZip/SevenZipStreamsCompressor.cs - New streams compressor
  • src/SharpCompress/Factories/SevenZipFactory.cs - Added IWriterFactory
  • src/SharpCompress/Writers/SevenZip/SevenZipWriter.Async.cs - Async support
  • src/SharpCompress/Writers/SevenZip/SevenZipWriter.Factory.cs - Factory methods
  • src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs - Main writer implementation
  • src/SharpCompress/Writers/SevenZip/SevenZipWriterOptions.cs - Writer options
  • src/SharpCompress/Writers/WriterOptionsExtensions.cs - LeaveStreamOpen support
  • tests/SharpCompress.Test/SevenZip/SevenZipWriterTests.cs - Comprehensive tests

Assessment: The implementation is well-structured with solid test coverage. The existing warning at line 97 has been partially addressed with the rewind fix. Consider verifying the empty stream handling works correctly with non-seekable streams before merging.

@adamhathcock
Copy link
Owner

This is great, I'll have to inspect hits closely

I was close to merging in a new PR that changes the API just for 7z files because you can't really do random access of bytes (extract them) as it's likely there's multiple files in a single stream. I'm interested in how you handled it.

@adamhathcock
Copy link
Owner

Looks like it's just the writer and does a compresssion stream per file. I'll sleep on it but probably want to take it as-is if the tests pass!

@DanNsk
Copy link
Contributor Author

DanNsk commented Feb 23, 2026

Looks like it's just the writer and does a compresssion stream per file. I'll sleep on it but probably want to take it as-is if the tests pass!

Yes it doesn't do solid archives yet, I honestly didn't want to add everything at once - just to make PR easier to comprehend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants