Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/rikyoz/bit7z

A C++ static library offering a clean and simple interface to the 7-zip shared libraries.
https://github.com/rikyoz/bit7z

7-zip 7z 7zip archives archives-metadata bzip2 c-plus-plus compression cpp cpp-library cross-platform encrypted-archives extraction gzip in-memory multi-volume-archives rar static-library tar zip

Last synced: about 2 months ago
JSON representation

A C++ static library offering a clean and simple interface to the 7-zip shared libraries.

Lists

README

        

bit7z

A C++ static library offering a clean and simple interface to the 7-zip shared libraries


Supported Features
Getting Started
Download
Requirements
Building & Using
Donate
License


GitHub releaseC++14WindowsLinuxmacOSx86, x64, arm, arm64donatedocsBuild status


MSVC 2015+GCC 4.9+Clang 3.6+CodeFactor GradeLicense

## ⚡️ Introduction

**bit7z** is a _cross-platform_ C++ static library that allows the _compression/extraction of archive files_ through a _clean_ and _simple_ wrapper interface to the dynamic libraries from the [7-zip](https://www.7-zip.org/ "7-zip Project Homepage") project.

It supports compression and extraction to and from the filesystem or the memory, reading archives metadata, updating existing ones, creating multi-volume archives, operation progress callbacks, and many other functionalities.

## 🎯 Supported Features

+ **Compression** using the following archive formats: **7z**, XZ, **BZIP2**, **GZIP**, TAR, **ZIP**, and WIM.
+ **Extraction** of many archive formats: **7z**, AR, ARJ, **BZIP2**, CAB, CHM, CPIO, CramFS, DEB, DMG, EXT, FAT, GPT, **GZIP**, HFS, HXS, IHEX, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, QCOW2, **RAR**, **RAR5**, RPM, SquashFS, TAR, UDF, UEFI, VDI, VHD, VMDK, WIM, XAR, XZ, Z, and **ZIP**.
+ **Reading metadata** of archives and their content.
+ **Testing** archives for errors.
+ **Updating** existing file archives with new files.
+ **Renaming**, **updating**, or **deleting** old items in existing file archives.
+ **Compression and extraction _to and from_ memory** and **C++ standard streams**.
+ Compression using **custom path aliases** for the items in the output archives.
+ **Selective extraction** of only specified files/folders **using wildcards** and **regular expressions**.
+ Creation of **encrypted archives** (strong AES-256 encryption; only for 7z and ZIP formats).
+ **Archive header encryption** (only for 7z format).
+ Possibility to choose the **compression level** (if supported by the archive format), the **compression method** ([supported methods](https://github.com/rikyoz/bit7z/wiki/Advanced-Usage#compression-methods "Wiki page on bit7z's supported compression methods")), the **dictionary size**, and the **word size**.
+ **Automatic input archive format detection**.
+ **Solid archives** (only for 7z).
+ **Multi-volume archives**.
+ **Operation callbacks** for obtaining real-time information about ongoing operations.
+ **Canceling** or **pausing** the current operation.

### Notes

The presence or not of some of the above features depends on the particular shared library used along with bit7z.

For example, 7z.dll should support all these features, 7za.dll should work only with the 7z file format, and 7zxa.dll can only extract 7z files. For more information about the 7-zip DLLs, please check this [wiki page](https://github.com/rikyoz/bit7z/wiki/7z-DLLs).

In the end, some other features (e.g., _automatic format detection_ and _selective extraction using regular expressions_) are disabled by default, and macro definitions must be used during compilation to have them available ([wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).

## 🔥 Getting Started (Library Usage)

Below are a few examples that show how to use some of the main features of bit7z.

### 📂 Extracting Files from an Archive

```cpp
#include

try { // bit7z classes can throw BitException objects
using namespace bit7z;

Bit7zLibrary lib{ "7za.dll" };
BitFileExtractor extractor{ lib, BitFormat::SevenZip };

// Extracting a simple archive
extractor.extract( "path/to/archive.7z", "out/dir/" );

// Extracting a specific file inside an archive
extractor.extractMatching( "path/to/archive.7z", "file.pdf", "out/dir/" );

// Extracting the first file of an archive to a buffer
std::vector< byte_t > buffer;
extractor.extract( "path/to/archive.7z", buffer );

// Extracting an encrypted archive
extractor.setPassword( "password" );
extractor.extract( "path/to/another/archive.7z", "out/dir/" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
```

Alternatively, if you only need to work on a single archive:

```cpp
#include

try { // bit7z classes can throw BitException objects
using namespace bit7z;

Bit7zLibrary lib{ "7z.dll" };

// Opening the archive
BitArchiveReader archive{ lib, "path/to/archive.gz", BitFormat::GZip };

// Testing the archive
archive.test();

// Extracting the archive
archive.extractTo( "out/dir/" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
```

### 💼 Compressing Files into an Archive

```cpp
#include

try { // bit7z classes can throw BitException objects
using namespace bit7z;

Bit7zLibrary lib{ "7z.dll" };
BitFileCompressor compressor{ lib, BitFormat::Zip };

std::vector< std::string > files = { "path/to/file1.jpg", "path/to/file2.pdf" };

// Creating a simple zip archive
compressor.compress( files, "output_archive.zip" );

// Creating a zip archive with a custom directory structure
std::map< std::string, std::string > files_map = {
{ "path/to/file1.jpg", "alias/path/file1.jpg" },
{ "path/to/file2.pdf", "alias/path/file2.pdf" }
};
compressor.compress( files_map, "output_archive2.zip" );

// Compressing a directory
compressor.compressDirectory( "dir/path/", "dir_archive.zip" );

// Creating an encrypted zip archive of two files
compressor.setPassword( "password" );
compressor.compressFiles( files, "protected_archive.zip" );

// Updating an existing zip archive
compressor.setUpdateMode( UpdateMode::Append );
compressor.compressFiles( files, "existing_archive.zip" );

// Compressing a single file into a buffer
std::vector< bit7z::byte_t > buffer;
BitFileCompressor compressor2{ lib, BitFormat::BZip2 };
compressor2.compressFile( files[0], buffer );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
```

Alternatively, if you only need to work on a single archive:

```cpp
#include

try { // bit7z classes can throw BitException objects
using namespace bit7z;

Bit7zLibrary lib{ "7z.dll" };
BitArchiveWriter archive{ lib, BitFormat::SevenZip };

// Adding the items to be compressed (no compression is performed here)
archive.addFile( "path/to/file.txt" );
archive.addDirectory( "path/to/dir/" );

// Compressing the added items to the output archive
archive.compressTo( "output.7z" );
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
```

### 📑 Reading Archive Metadata

```cpp
#include

try { // bit7z classes can throw BitException objects
using namespace bit7z;

Bit7zLibrary lib{ "7za.dll" };
BitArchiveReader arc{ lib, "archive.7z", BitFormat::SevenZip };

// Printing archive metadata
std::cout << "Archive properties\n";
std::cout << " Items count: " << arc.itemsCount() << '\n';
std::cout << " Folders count: " << arc.foldersCount() << '\n';
std::cout << " Files count: " << arc.filesCount() << '\n';
std::cout << " Size: " << arc.size() <<'\n';
std::cout << " Packed size: " << arc.packSize() << "\n\n";

// Printing the metadata of the archived items
std::cout << "Archived items";
for ( const auto& item : arc ) {
std::cout << '\n';
std::cout << " Item index: " << item.index() << '\n';
std::cout << " Name: " << item.name() << '\n';
std::cout << " Extension: " << item.extension() << '\n';
std::cout << " Path: " << item.path() << '\n';
std::cout << " IsDir: " << item.isDir() << '\n';
std::cout << " Size: " << item.size() << '\n';
std::cout << " Packed size: " << item.packSize() << '\n';
std::cout << " CRC: " << std::hex << item.crc() << std::dec << '\n';
}
std::cout.flush();
} catch ( const bit7z::BitException& ex ) { /* Do something with ex.what()...*/ }
```

A complete _**API reference**_ is available in the [wiki](https://github.com/rikyoz/bit7z/wiki/) section.

### 🚀 Upgrading from bit7z v3 to v4

The newest bit7z v4 introduced some significant breaking changes to the library's API.

Expand for more details!

+ By default, the project now follows the [UTF-8 Everywhere Manifesto](http://utf8everywhere.org/):
+ The default string type is `std::string` (instead of `std::wstring`), so users can use the library in cross-platform projects more easily (v4 introduced Linux/macOS support too).
+ Input `std::string`s will be considered as UTF-8 encoded.
+ You can still achieve the old behavior on Windows using the `-DBIT7Z_USE_NATIVE_STRING` CMake option.
+ The old `BitExtractor` class is now called `BitFileExtractor`.
+ Now `BitExtractor` is just the name of a template class for all the extraction classes.
+ The old `BitCompressor` class is now called `BitFileCompressor`.
+ Now `BitCompressor` is just the name of a template class for all the compression classes.
+ The `ProgressCallback` now must return a `bool` value indicating whether the current operation can continue (`true`) or not (`false`).
+ The project structure changed:
+ Public API headers moved from `include/` to the `include/bit7z/` folder, so `#include` directives now need to prepend `bit7z/` to the included header name (e.g., `#include `).
+ Even though it is a bit verbose, it is a typical structure for C and C++ libraries, and it makes explicit which third-party library a header file belongs to.
+ By default, the output folder of bit7z is now `lib//`; if the CMake generator is multi-config (e.g., Visual Studio generators), the default output folder is `lib///`.
+ Optionally, you can force using the "Visual Studio style" output path by enabling the `BIT7Z_VS_LIBNAME_OUTDIR_STYLE` CMake option.
+ Third-party dependencies are no longer handled using git submodules but are automatically downloaded using [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) when configuring/using the library via CMake.

## 💾 Download


GitHub Latest Release



GitHub All Releases

Each released package contains:

+ A _pre-compiled version_ of bit7z (both in _debug_ and _release_ mode);
+ The _public API headers_ needed to use the library in your program;

Packages are available for both _x86_ and _x64_ architectures.

You can also clone/download this repository and build the library yourself (please, read the [wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library)).

## 🧰 Requirements

+ **Operating System:** Windows, Linux, macOS, Android[^1].
+ **Architecture:** x86, x86_64, arm, arm64.
+ **Language Standard:** C++11 (for using the library), C++14 (for building the library).
+ **Compiler:** MSVC 2015 or later[^2], MinGW v6.4 or later, GCC v4.9 or later, Clang 3.6 or later.
+ **Shared Library:** a 7-zip `.dll` library on Windows, a 7-zip/p7zip `.so` library on Unix[^3].

[^1]: On Windows, you should link your program _also_ with _oleaut32_ (e.g., `-lbit7z -loleaut32`).
On Linux and macOS, you should link your program _also_ with _dl_ (e.g., `-lbit7z -ldl`).
If you are using the library via CMake, these dependencies will be linked automatically to your project.

[^2]: MSVC 2010 was supported until v2.x, MSVC 2012/2013 until v3.x.

[^3]: bit7z doesn't ship with the 7-zip shared libraries. You can build them from the source code available at [7-zip.org](http://www.7-zip.org/).

## ⚙️ Building and Using bit7z

For building the library:

```bash
cd
mkdir build && cd build
cmake ../ -DCMAKE_BUILD_TYPE=Release
cmake --build . -j --config Release
```

A more detailed guide on how to build this library is available [here](https://github.com/rikyoz/bit7z/wiki/Building-the-library).

You can also directly integrate the library into your project via CMake:

+ Download bit7z and copy it into a sub-directory of your project (e.g., `third_party`), or add it as a git submodule of your repository.
+ Then, use the command `add_subdirectory()` in your `CMakeLists.txt` to include bit7z.
+ Finally, link the `bit7z` library using the `target_link_libraries()` command.

For example:

```cmake
add_subdirectory( ${CMAKE_SOURCE_DIR}/third_party/bit7z )
target_link_libraries( ${YOUR_TARGET} PRIVATE bit7z )
```

The library is highly customizable: for a detailed list of the available build options, please refer to the [wiki](https://github.com/rikyoz/bit7z/wiki/Building-the-library).

### 📑 7-zip Version

While configuring bit7z via CMake, it automatically downloads the latest version of 7-zip currently supported by the library.

Optionally, you can specify a different version of 7-zip via the CMake option `BIT7Z_7ZIP_VERSION` (e.g., `-DBIT7Z_7ZIP_VERSION="22.01"`).

Alternatively, you can specify a custom path containing the 7-zip source code via the option `BIT7Z_CUSTOM_7ZIP_PATH`.

Please note that, in general, it is best to use the same version of 7-zip of the shared libraries that you will use at runtime.

#### Using 7-zip v23.01 on Linux and macOS

Expand for more details!

_On Linux and macOS_, 7-zip v23.01 introduced breaking changes to the IUnknown interface. If you build bit7z for such a version of 7-zip (the default), it will not support using the shared libraries from previous versions of 7-zip (or from p7zip). Conversely, bit7z made for earlier versions of 7-zip or for p7zip is incompatible with the shared libraries from 7-zip v23.01 and later.

You can build the shared libraries of 7-zip v23.01 in a backward-compatible mode by defining the macro `Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN`. If this is your case, you can build bit7z for v23.01 using the option `BIT7Z_USE_LEGACY_IUNKNOWN` (in this case, bit7z will be compatible also with previous versions of 7-zip/p7zip).

### 🌐 String Encoding

By default, bit7z follows the [UTF-8 Everywhere Manifesto](http://utf8everywhere.org/) to simplify the use of the library within cross-platform projects.
In short, this means that:

+ The default path string type is `std::string`.
+ Input `std::string`s are considered as UTF-8 encoded; output `std::string`s are UTF-8 encoded.

Expand for more details and for other string encoding options!

On POSIX systems, `std::string`s are usually already UTF-8 encoded, and no configuration is needed.

The situation is a bit more complex on Windows since, by default, Windows treats `std::string`s as encoded using the system code page, which may not necessarily be UTF-8, like, for example, [Windows-1252](https://en.wikipedia.org/wiki/Windows-1252).

If your program deals exclusively with ASCII-only strings, you should be fine with the default bit7z settings (as ASCII characters are also UTF-8).

However, if you need to handle non-ASCII/Unicode characters, as it is likely, you have the following options:

+ Enforcing using the UTF-8 code page for your whole application, as explained by Microsoft [here](https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page):
+ _**Recommended**_, but supported only since Windows 10 1903 and later.
+ Manually ensuring the encoding of the `std::string`s passed to bit7z:
+ You can use some string encoding library or C++11's UTF-8 string literals for input strings.
+ User-input strings (e.g., the password of an archive) can be handled as explained [here](https://nullprogram.com/blog/2020/05/04/); in short: read the input as an UTF-16 wide string (e.g., via `ReadConsoleW`), and convert it to UTF-8 (bit7z provides a utility function for this, `bit7z::to_tstring`).
+ You can correctly print the UTF-8 output strings from bit7z (e.g., the path/name metadata of a file in an archive) to the console by calling [`SetConsoleOutputCP(CP_UTF8)`](https://learn.microsoft.com/en-us/windows/console/setconsoleoutputcp) before.
+ Configuring bit7z to use UTF-16 encoded wide strings (i.e., `std::wstring`) by enabling the `BIT7Z_USE_NATIVE_STRING` option via CMake.
+ If your program is Windows-only, or you already use wide strings on Windows, this might be the best choice since it will avoid any internal string conversions (7-zip always uses wide strings).
+ This option makes developing cross-platform applications slightly inconvenient since you'll still have to use `std::string` on POSIX systems.
+ The library provides a type alias `bit7z::tstring` and a macro function `BIT7Z_STRING` for defining wide string variables and literals on Windows and narrow ones on other platforms.
+ You must programmatically set the standard input and output encoding to UTF-16 to correctly read and print Unicode characters:

```cpp
#include //for _O_U16TEXT
#include //for _setmode

_setmode(_fileno(stdout), _O_U16TEXT); // setting the stdout encoding to UTF16
_setmode(_fileno(stdin), _O_U16TEXT); // setting the stdin encoding to UTF16
```

+ Configuring bit7z to use the system code page encoding for `std::string` by enabling the `BIT7Z_USE_SYSTEM_CODEPAGE` option via CMake.
+ _Not recommended_: using this option, your program will be limited in the set of characters it can pass to and read from bit7z.

## ☕️ Donate

If you have found this project helpful, please consider supporting me with a small donation so that I can keep improving it!
Thank you! :pray:


Sponsor me on GitHubBuy Me a Coffee at ko-fi.comDonations

## 📜 License

This project is licensed under the terms of the [Mozilla Public License v2.0](https://www.mozilla.org/en-US/MPL/2.0/).

For more details, please check:

+ The [LICENSE](./LICENSE) file.
+ [Mozilla's MPL-2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/)

Older versions (v3.x and earlier) of bit7z were released under the [GNU General Public License v2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html).




Copyright © 2014 - 2023 Riccardo Ostani (@rikyoz)