PLzmaSDK 是 (Portable, Patched, Package, cross-P-latform) Lzma SDK。基于原始的 LZMA SDK 版本 22.01 (2201 - 目前最新) 并针对 Unix 平台进行了修复。适用于所有 Apple 平台(iOS, macOS, tvOS, watchOS),Android,Windows,Linux 和任何 Unix 系统。
功能/详细信息
- SDK 可用于以下编程语言
- 通过 Swift 和 Swift Package Manager 或 CocoaPods。
- 通过 JavaScript 和 npm。
- 纯 C++,通过 git + CMake 或将 2 个主要库头文件(libplzma.h 和 libplzma.hpp)和 src 文件夹复制到您的项目中。
- 纯 C,也通过 git + CMake 或将 2 个主要库头文件(libplzma.h 和 libplzma.hpp)和 src 文件夹复制到您的项目中。但是,可以通过 CMake 的布尔选项
LIBPLZMA_OPT_NO_C_BINDINGS:BOOL=YES
或预处理定义LIBPLZMA_NO_C_BINDINGS=1
禁用内部 C 绑定代码,见下文。
- 支持以下存档格式
- 支持列表、测试、提取和压缩操作。所有这些操作都可以在单独的线程中执行并在过程中中断。
- 支持《7z》多卷存档。
- 线程安全的编码器、解码器和进度跟踪。根据使用情况,您可以通过 CMake 的布尔选项
LIBPLZMA_OPT_THREAD_UNSAFE:BOOL=YES
或预处理定义LIBPLZMA_THREAD_UNSAFE=1
禁用所有线程同步。 - 支持内存和文件 IO 流。提取和压缩可以从内存或文件双向转换。
- 支持提取和压缩文件大小超过 4GB 的存档文件(x64 支持)。
- 跟踪平滑进度。
- 全面支持 UTF8。
- 支持任何拥有支持C++11标准的编译器的平台。比如说,现在几乎到处都是。
- 无外部依赖。也不使用STL(当然不在公共接口和内部)。
- SDK 同时以 C 和 C++ 库的形式组织。且支持静态和动态链接。
- libplzma.h - 纯 C 环境下的库头文件。包含通用函数、类型,以及可选绑定到库的全部功能。目前可使用 Swift 包管理器 和 CocoaPods。
- libplzma.hpp - 纯 C++ 环境下的库头文件,必须与 libplzma.h 头文件一起使用。目前可用于 npm 原生模块。
- 包含 SDK 的 Swift 部分的是 swift 目录,并通过 Swift 包管理器 和 CocoaPods 提供使用,详见
安装
部分。 - 包含 node 目录的 Node.js 原生和内联模块实现。
可选功能
所有可选功能默认启用,但在构建过程中可能会禁用它们以减小二进制文件大小,当然,如果您不计划使用它们,也可以禁用。
- tar/tarball 存档支持。要禁用,使用 CMake 的布尔选项
LIBPLZMA_OPT_NO_TAR:BOOL=YES
或编译器定义LIBPLZMA_NO_TAR=1
- 线程安全。要禁用,使用 CMake 的布尔选项
LIBPLZMA_OPT_THREAD_UNSAFE:BOOL=YES
或编译器定义LIBPLZMA_THREAD_UNSAFE=1
- 进度跟踪。要禁用,使用 CMake 的布尔选项
LIBPLZMA_OPT_NO_PROGRESS:BOOL=YES
或编译器定义LIBPLZMA_NO_PROGRESS=1
- libplzma.h 头文件中提供了对库全部功能的 C 语言绑定。要禁用,使用 CMake 的布尔选项
LIBPLZMA_OPT_NO_C_BINDINGS:BOOL=YES
或编译器定义LIBPLZMA_NO_C_BINDINGS=1
- 加密功能。不推荐!但在技术上是可能的。仅在您了解自己在做什么时才这样做!要禁用,使用 CMake 的布尔选项
LIBPLZMA_OPT_NO_CRYPTO:BOOL=YES
或编译器定义LIBPLZMA_NO_CRYPTO=1
安装
Swift包包管理器
.package(url: "https://github.com/OlehKulykov/PLzmaSDK.git", .exact("1.2.5"))
CocoaPods Podfile
use_frameworks!
platform :ios, '9.0'
target '<REPLACE_WITH_YOUR_TARGET>' do
pod 'PLzmaSDK', '1.2.5'
end
通过 'package.json' 使用 npm
{
"engines": {
"node": ">=13.0.0",
"npm": ">=6.0.0"
},
"dependencies": {
"plzmasdk": "1.2.5"
}
}
Android NDK
cd <PATH_TO_ANDROID_NDK>
./ndk-build NDK_PROJECT_PATH=<PATH_TO_PLZMASDK>/PLzmaSDK/android
CMake Unix
cd PLzmaSDK
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j4
CMake Windows
cd PLzmaSDK
md build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release --parallel 4
示例
提取或测试
打开,列出并选择要提取或测试的存档项。
此过程分为四个步骤
- 创建一个源输入流以读取存档文件内容。输入流可以创建为
- 存档文件的路径。
- 存档文件内容在内存中,即使用const内存或其副本进行内部使用。
- 自定义读取/查找回调(仅限C/C++)。
- 使用源输入流创建解码器、存档类型和可选进度代表。
- 可选提供密码以打开和列出加密存档,以及未来的提取或测试。
- 选择要提取或测试的存档项。如果您想处理所有项(整个存档),则可以跳过以下步骤。
- 以原样选择所有存档项。
- 检索项目数量,通过索引迭代它们,过滤和/或选择。
- 提取或测试选定的存档项。提取过程可能包括
- 将所有项目提取到目录中。在这种情况下,可以跳过第3步。
- 将选定的项目提取到目录中。
- 将每个项目提取到自定义输出流中。输出流可以是文件或内存。例如,将“项目编号1”提取到文件流中,将“项目编号2”提取到内存流中(然后取出提取的内存),依此类推。
Swift
do {
// 1. Create a source input stream for reading archive file content.
// 1.1. Create a source input stream with the path to an archive file.
let archivePath = try Path("path/to/archive.7z")
let archivePathInStream = try InStream(path: archivePath)
// 1.2. Create a source input stream with the file content.
let archiveData = Data(...)
let archiveDataInStream = try InStream(dataNoCopy: archiveData) // also available Data(dataCopy: Data)
// 2. Create decoder with source input stream, type of archive and optional delegate.
let decoder = try Decoder(stream: archiveDataInStream /* archivePathInStream */, fileType: .sevenZ, delegate: self)
// 2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.
try decoder.setPassword("1234")
let opened = try decoder.open()
// 3. Select archive items for extracting or testing.
// 3.1. Select all archive items.
let allArchiveItems = try decoder.items()
// 3.2. Get the number of items, iterate items by index, filter and select items.
let numberOfArchiveItems = try decoder.count()
let selectedItemsDuringIteration = try ItemArray(capacity: numberOfArchiveItems)
let selectedItemsToStreams = try ItemOutStreamArray()
for itemIndex in 0..<numberOfArchiveItems {
let item = try decoder.item(at: itemIndex)
try selectedItemsDuringIteration.add(item: item)
try selectedItemsToStreams.add(item: item, stream: OutStream()) // to memory stream
}
// 4. Extract or test selected archive items. The extract process might be:
// 4.1. Extract all items to a directory. In this case, you can skip the step #3.
let extracted = try decoder.extract(to: Path("path/outdir"))
// 4.2. Extract selected items to a directory.
let extracted = try decoder.extract(items: selectedItemsDuringIteration, to: Path("path/outdir"))
// 4.3. Extract each item to a custom out-stream.
// The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.
let extracted = try decoder.extract(itemsToStreams: selectedItemsToStreams)
} catch let exception as Exception {
print("Exception: \(exception)")
}
JavaScript
const plzma = require('plzmasdk');
try {
// 1. Create a source input stream for reading archive file content.
// 1.1. Create a source input stream with the path to an archive file.
const archivePath = plzma.Path(__dirname).append('path/to/archive.7z');
const archivePathInStream = new plzma.InStream(archivePath /* 'path/to/archive.7z' */);
// 1.2. Create a source input stream with the file content.
const archiveData = new ArrayBuffer(...);
const archiveDataInStream = new plzma.InStream(archiveData);
// 2. Create decoder with source input stream, type of archive and optional delegate.
const decoder = new plzma.Decoder(archivePathInStream, plzma.FileType.sevenZ);
decoder.setProgressDelegate((path, progress) => console.log(`Delegating progress, path: ${path}, progress: ${progress}`) );
// 2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.
decoder.setPassword('1234');
const opened = await decoder.openAsync(); // also available sync. version 'decoder.open()'
// 3. Select archive items for extracting or testing.
// 3.1. Select all archive items.
const allArchiveItems = decoder.items;
// 3.2. Get the number of items, iterate items by index, filter and select items.
const selectedItemsDuringIteration = [];
const selectedItemsToStreams = new Map();
for (let itemIndex = 0, numberOfArchiveItems = decoder.count; itemIndex < numberOfArchiveItems; itemIndex++) {
const item = decoder.itemAt(itemIndex);
selectedItemsDuringIteration.push(item);
selectedItemsToStreams.set(item, plzma.OutStream()); // to memory stream
}
// 4. Extract or test selected archive items. The extract process might be:
// 4.1. Extract all items to a directory. In this case, you can skip the step #3.
const extracted = await decoder.extractAsync('path/outdir'); // also available sync. version 'decoder.extract()'
// 4.2. Extract selected items to a directory.
const extracted = await decoder.extractAsync(selectedItemsDuringIteration, 'path/outdir'); // also available sync. version 'decoder.extract()'
// 4.3. Extract each item to a custom out-stream.
// The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.
const extracted = await decoder.extractAsync(selectedItemsToStreams); // also available sync. version 'decoder.extract()'
} catch (error) {
console.log(`Exception: ${error}`);
}
C++
try {
// 1. Create a source input stream for reading archive file content.
// 1.1. Create a source input stream with the path to an archive file.
Path archivePath("path/to/archive.7z"); // Path(L"C:\\\\path\\to\\archive.7z");
auto archivePathInStream = makeSharedInStream(archivePath /* std::move(archivePath) */);
// 1.2. Create a source input stream with the file content.
auto archiveDataInStream = makeSharedInStream(<FILE DATA>, <FILE SIZE>);
// 2. Create decoder with source input stream, type of archive and provide optional delegate.
auto decoder = makeSharedDecoder(archiveDataInStream, plzma_file_type_7z);
decoder->setProgressDelegate(this);
// 2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.
decoder->setPassword("1234"); // decoder->setPassword(L"1234");
bool opened = decoder->open();
// 3. Select archive items for extracting or testing.
// 3.1. Select all archive items.
auto allArchiveItems = decoder->items();
// 3.2. Get the number of items, iterate items by index, filter and select items.
size_t numberOfArchiveItems = decoder->count();
auto selectedItemsDuringIteration = makeShared<ItemArray>(numberOfArchiveItems);
auto selectedItemsToStreams = makeShared<ItemOutStreamArray>();
for (size_t itemIndex = 0; itemIndex < numberOfArchiveItems; itemIndex++) {
auto item = decoder->itemAt(itemIndex);
selectedItemsDuringIteration->push(item /* std::move(item) */);
selectedItemsToStreams->push(Pair<SharedPtr<Item>, SharedPtr<OutStream> >(item, makeSharedOutStream())); // to memory stream
}
// 4. Extract or test selected archive items. The extract process might be:
// 4.1. Extract all items to a directory. In this case, you can skip the step #3.
bool extracted = decoder->extract(Path("path/outdir"));
// 4.2. Extract selected items to a directory.
bool extracted = decoder->extract(selectedItemsDuringIteration, Path("path/outdir"));
// 4.3. Extract each item to a custom out-stream.
// The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.
bool extracted = decoder->extract(selectedItemsToStreams);
} catch (const Exception & exception) {
std::cout << "Exception: " << exception.what() << std::endl;
}
C
// 1. Create a source input stream for reading archive file content.
// 1.1. Create a source input stream with the path to an archive file.
plzma_path archivePath = plzma_path_create_with_utf8_string("path/to/archive.7z"); // plzma_path_create_with_wide_string(L"C:\\\\path\\to\\archive.7z");
plzma_in_stream archivePathInStream = plzma_in_stream_create_with_path(&archivePath); // plzma_in_stream_create_with_pathm(...);
plzma_path_release(&archivePath);
plzma_in_stream_release(&archivePathInStream); // when no longer needed
// 1.2. Create a source input stream with the file content in memory.
plzma_in_stream archiveDataInStream = plzma_in_stream_create_with_memory_copy(<FILE DATA>, <FILE SIZE>); // plzma_in_stream_create_with_memory(...);
// 2. Create decoder with source input stream, type of archive, context for optional delegate and provide optional delegate callback.
plzma_decoder decoder = plzma_decoder_create(&archiveDataInStream, plzma_file_type_7z, plzma_context{ nullptr, nullptr }); // C2059 = { .context = nullptr, .deinitializer = nullptr }
plzma_in_stream_release(&archiveDataInStream); // when no longer needed
plzma_decoder_set_progress_delegate_utf8_callback(&decoder, <UTF8 C CALLBACK>); // plzma_decoder_set_progress_delegate_wide_callback(...);
// 2.1. Optionaly provide the password to open/list/test/extract encrypted archive items.
plzma_decoder_set_password_utf8_string(&decoder, "1234"); // plzma_decoder_set_password_wide_string(&decoder, L"1234");
bool opened = plzma_decoder_open(&decoder);
// 3. Select archive items for extracting or testing.
// 3.1. Select all archive items.
plzma_item_array allArchiveItems = plzma_decoder_items(&decoder);
// 3.2. Get the number of items, iterate items by index, filter and select items.
size_t numberOfArchiveItems = plzma_decoder_count(&decoder);
plzma_item_array selectedItemsDuringIteration = plzma_item_array_create(numberOfArchiveItems);
plzma_item_out_stream_array selectedItemsToStreams = plzma_item_out_stream_array_create(numberOfArchiveItems);
for (size_t itemIndex = 0; itemIndex < numberOfArchiveItems; itemIndex++) {
plzma_item item = plzma_decoder_item_at(&decoder, itemIndex);
plzma_item_array_add(&selectedItemsDuringIteration, &item);
plzma_out_stream outItemStream = plzma_out_stream_create_memory_stream(); // to memory stream
plzma_item_out_stream_array_add(&selectedItemsToStreams, &item, &outItemStream);
plzma_out_stream_release(&outItemStream);
plzma_item_release(&item);
}
// 4. Extract or test selected archive items. The extract process might be:
// 4.1. Extract all items to a directory. In this case, you can skip the step #3.
plzma_path extractPath = plzma_path_create_with_utf8_string("path/outdir");
bool extracted = plzma_decoder_extract_all_items_to_path(&decoder, &extractPath, true);
plzma_path_release(&extractPath);
// 4.2. Extract selected items to a directory.
plzma_path extractPath = plzma_path_create_with_utf8_string("path/outdir");
bool extracted = plzma_decoder_extract_items_to_path(&decoder, &selectedItemsDuringIteration, &extractPath, true);
plzma_path_release(&extractPath);
// 4.3. Extract each item to a custom out-stream.
// The out-stream might be a file or memory. I.e. extract 'item #1' to a file stream, extract 'item #2' to a memory stream(then take extacted memory) and so on.
bool extracted = plzma_decoder_extract_item_out_stream_array(&decoder, &selectedItemsToStreams);
plzma_item_array_release(&selectedItemsDuringIteration); // when no longer needed
plzma_item_array_release(&allArchiveItems); // when no longer needed
plzma_item_out_stream_array_release(&selectedItemsToStreams); // when no longer needed
plzma_decoder_release(&decoder); // when no longer needed
压缩
创建输出,设置编码器/存档,添加内容,打开并压缩。
该过程包括 4 个步骤
- 创建用于写入存档文件内容的输出流。输出流可能通过以下方式创建:
- 存档文件的路径。
- 不带任何参数创建内存流。
- 使用输出流创建编码器,存档类型、压缩方法以及可选的进度代理。
- 在需要加密标题和/或内容的情况下,可选提供密码。
- 设置存档属性。
- 添加存档内容。内容可能是以下之一
- 包含存档内路径的单个文件路径(可选)。
- 包含可选目录迭代选项和存档内路径的单个目录路径。
- 包含必需存档内路径的任何输入流。
- 打开并压缩。
Swift
do {
// 1. Create output stream for writing archive's file content.
// 1.1. Using file path.
let archivePath = Path("path/out.7z");
let archivePathOutStream = try OutStream(path: archivePath)
// 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.
let encoder = try Encoder(stream: archivePathOutStream, fileType: .sevenZ, method: .LZMA2, delegate: self)
// 2.1. Optionaly provide the password in case of header and/or content encryption.
try encoder.setPassword("1234")
// 2.2. Setup archive properties.
try encoder.setShouldEncryptHeader(true) // use this option with password.
try encoder.setShouldEncryptContent(true) // use this option with password.
try encoder.setCompressionLevel(9)
// 3. Add content for archiving.
// 3.1. Single file path with optional path inside the archive.
try encoder.add(path: Path("dir/my_file1.txt")) // store as "dir/my_file1.txt", as is.
try encoder.add(path: Path("dir/my_file2.txt"), mode: .default, archivePath: Path("renamed_file2.txt")) // store as "renamed_file2.txt"
// 3.2. Single directory path with optional directory iteration option and optional path inside the archive.
try encoder.add(path: Path("dir/dir1")) // store as "dir1/..."
try encoder.add(path: Path("dir/dir2"), mode: .followSymlinks, archivePath: Path("renamed_dir2")) // store as "renamed_dir2/..."
// 3.3. Any input stream with required path inside the archive.
let itemStream = try InStream(dataCopy: <Data>) // InStream(dataNoCopy: <Data>)
try encoder.add(stream: itemStream, archivePath: Path("my_file3.txt")) // store as "my_file3.txt"
// 4. Open.
let opened = try encoder.open()
// 4. Compress.
let compressed = try encoder.compress()
} catch let exception as Exception {
print("Exception: \(exception)")
}
JavaScript
const plzma = require('plzmasdk');
try {
// 1. Create output stream for writing archive's file content.
// 1.1. Using file path.
const archivePathOutStream = new plzma.OutStream('path/out.7z');
// 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.
const encoder = plzma.Encoder(archivePathOutStream, plzma.FileType.sevenZ, plzma.Method.LZMA2);
encoder.setProgressDelegate((path, progress) => console.log(`Delegating progress, path: ${path}, progress: ${progress}`) );
// 2.1. Optionaly provide the password in case of header and/or content encryption.
encoder.setPassword('1234');
// 2.2. Setup archive properties.
encoder.shouldEncryptHeader = true; // use this option with password.
encoder.shouldEncryptContent = true; // use this option with password.
encoder.compressionLevel = 9;
// 3. Add content for archiving.
// 3.1. Single file path with optional path inside the archive.
encoder.add('dir/my_file1.txt'); // store as "dir/my_file1.txt", as is.
encoder.add('dir/my_file2.txt', 0, 'renamed_file2.txt'); // store as "renamed_file2.txt"
// 3.2. Single directory path with optional directory iteration option and optional path inside the archive.
encoder.add('dir/dir1'); // store as "dir1/..."
encoder.add('dir/dir2', plzma.OpenDirMode.followSymlinks, 'renamed_dir2'); // store as "renamed_dir2/..."
// 3.3. Any input stream with required path inside the archive.
const itemStream = plzma.InStream(new ArrayBuffer(...));
encoder.add(itemStream, 'my_file3.txt'); // store as "my_file3.txt"
// 4. Open.
const opened = await encoder.openAsync(); // also available sync. version 'encoder.open()'
// 4. Compress.
const compressed = await encoder.compressAsync(); // also available sync. version 'encoder.compress()'
} catch (error) {
console.log(`Exception: ${error}`);
}
C++
try {
// 1. Create output stream for writing archive's file content.
// 1.1. Using file path.
const auto archivePathOutStream = makeSharedOutStream(Path("path/out.7z"));
// 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.
auto encoder = makeSharedEncoder(archivePathOutStream, plzma_file_type_7z, plzma_method_LZMA2);
encoder->setProgressDelegate(_progressDelegate);
// 2.1. Optionaly provide the password in case of header and/or content encryption.
encoder->setPassword("1234");
// 2.2. Setup archive properties.
encoder->setShouldEncryptHeader(true); // use this option with password.
encoder->setShouldEncryptContent(true); // use this option with password.
encoder->setCompressionLevel(9);
// 3. Add content for archiving.
// 3.1. Single file path with optional path inside the archive.
encoder->add(Path("dir/my_file1.txt")); // store as "dir/my_file1.txt", as is.
encoder->add(Path("dir/my_file2.txt"), 0, Path("renamed_file2.txt")); // store as "renamed_file2.txt"
// 3.2. Single directory path with optional directory iteration option and optional path inside the archive.
encoder->add(Path("dir/dir1")); // store as "dir1/..."
encoder->add(Path("dir/dir2"), plzma_open_dir_mode_follow_symlinks, Path("renamed_dir2")); // store as "renamed_dir2/..."
// 3.3. Any input stream with required path inside the archive.
auto itemStream = makeSharedInStream(<DATA>, <DATA_SIZE>);
encoder->add(itemStream, Path("my_file3.txt")); // store as "my_file3.txt"
// 4. Open.
bool opened = encoder->open();
// 4. Compress.
bool compressed = encoder->compress();
} catch (const Exception & exception) {
std::cout << "Exception: " << exception.what() << std::endl;
}
C
// 1. Create output stream for writing archive's file content.
// 1.1. Using file path.
plzma_path archivePath = plzma_path_create_with_utf8_string("path/out.7z");
plzma_out_stream archivePathOutStream = plzma_out_stream_create_with_path(&archivePath);
// 2. Create encoder with output stream, type of the archive, compression method and optional progress delegate.
plzma_context context;
plzma_encoder encoder = plzma_encoder_create(&archivePathOutStream, plzma_file_type_7z, plzma_method_LZMA2, context);
plzma_encoder_set_progress_delegate_utf8_callback(&encoder, <C_CALLBACK_FUNCTION>);
// 2.1. Optionaly provide the password in case of header and/or content encryption.
plzma_encoder_set_password_utf8_string(&encoder, "1234");
// 2.2. Setup archive properties.
plzma_encoder_set_should_encrypt_header(&encoder, true); // use this option with password.
plzma_encoder_set_should_encrypt_content(&encoder, true); // use this option with password.
plzma_encoder_set_compression_level(&encoder, 9);
// 3. Add content for archiving.
// 3.1. Single file path with optional path inside the archive.
plzma_path itemPath = plzma_path_create_with_utf8_string("dir/my_file1.txt");
plzma_encoder_add_path(&encoder, &itemPath, 0, NULL); // store as "dir/my_file1.txt", as is.
plzma_path_release(&itemPath);
itemPath = plzma_path_create_with_utf8_string("dir/my_file2.txt");
plzma_path itemArchivePath = plzma_path_create_with_utf8_string("renamed_file2.txt");
plzma_encoder_add_path(&encoder, &itemPath, 0, &itemArchivePath); // store as "renamed_file2.txt"
plzma_path_release(&itemPath);
plzma_path_release(&itemArchivePath);
// 3.2. Single directory path with optional directory iteration option and optional path inside the archive.
itemPath = plzma_path_create_with_utf8_string("dir/dir1");
plzma_encoder_add_path(&encoder, &itemPath, 0, NULL); // store as "dir1/..."
plzma_path_release(&itemPath);
itemPath = plzma_path_create_with_utf8_string("dir/dir2");
itemArchivePath = plzma_path_create_with_utf8_string("renamed_dir2");
plzma_encoder_add_path(&encoder, &itemPath, plzma_open_dir_mode_follow_symlinks, &itemArchivePath); // store as "renamed_dir2/..."
plzma_path_release(&itemPath);
plzma_path_release(&itemArchivePath);
// 3.3. Any input stream with required path inside the archive.
itemArchivePath = plzma_path_create_with_utf8_string("my_file3.txt");
plzma_in_stream itemStream = plzma_in_stream_create_with_memory(<DATA>, <DATA_SIZE>);
plzma_encoder_add_stream(&encoder, &itemStream, &itemArchivePath); // store as "my_file3.txt"
plzma_in_stream_release(&itemStream);
plzma_path_release(&itemArchivePath);
// 4. Open.
bool opened = plzma_encoder_open(&encoder);
// 4. Compress.
bool compressed = plzma_encoder_compress(&encoder);
plzma_out_stream_release(&archivePathOutStream); // when no longer needed
plzma_path_release(&archivePath); // when no longer needed
plzma_encoder_release(&encoder); // when no longer needed
许可证
使用本项服务即表示您接受原始LZMA SDK和MIT许可证(见下文)
MIT许可证(MIT)
版权所有 © 2015 - 2022 Oleh Kulykov [email protected]
在此特此授予任何获得此软件及其相关文档(简称“软件”)副本的个人免费权利,以不受限制地处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许获取该软件的个人这样做,但应遵守以下条件
所有副本或软件的实质性部分都应包含上述版权声明和本许可声明。
软件按“原样”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、针对特定用途的适用性和非侵权性。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论此类索赔、损害或其他责任是由合同行为、侵权行为或其他行为引起的,即便在软件或软件的使用或其他交易中可能产生。