PLzmaSDK 是 (Portable, Patched, Package, cross-P-latform) Lzma SDK。基于原始的 LZMA SDK 版本 23.01,并为 Unix 平台进行了修改。适用于所有 Apple 的平台(iOS、macOS、tvOS、watchOS)、Android、Windows、Linux 和任何 Unix 系统。
特性 / 详细描述
- SDK 可用于以下编程语言
- Swift 通过 Swift Package Manager 或 CocoaPods。
- Objective-C 通过 CocoaPods。
- JavaScript 通过 npm。
- 纯 C++ 通过 git + CMake 或将 2 个主要库头文件(libplzma.h 和 libplzma.hpp 文件)和 src 文件夹复制到您的项目中。
- 纯 C,也通过 git + CMake 或将 2 个主要库头文件(libplzma.h 和 libplzma.hpp 文件)和 src 文件夹复制到您的项目中。但如果要禁用内部 C 绑定代码,可以通过 CMake 的布尔选项
LIBPLZMA_OPT_NO_C_BINDINGS:BOOL=YES
或预处理定义LIBPLZMA_NO_C_BINDINGS=1
来实现,如下所示。
- 支持以下存档
- 支持列表、测试、提取和压缩操作。所有这些操作都可以在单独的线程中执行,并在过程中可以中断。
- 支持 7z 多卷存档。
- 线程安全的编码、解码和进度跟踪。根据使用情况,您可以通过 CMake 的布尔选项
LIBPLZMA_OPT_THREAD_UNSAFE:BOOL=YES
或预处理器定义LIBPLZMA_THREAD_UNSAFE=1
来禁用所有线程同步。 - 支持内存和文件 I/O 流。提取和压缩可以从内存或文件中进行。
- 支持提取和压缩超过 4GB 大小的存档文件(支持 x64)。
- 跟踪平滑的进度。
- 全面支持 UTF8。
- 几乎在所有支持 C++11 标准的平台上都可用。现在几乎到处都是。
- 没有外部依赖。并且没有 STL(当然不是公开接口和内部)。
- SDK 同时组织为 C 和 C++ 库。并支持静态和动态链接。
- libplzma.h - 纯 C 环境的库头文件。包含通用功能、类型和可选绑定到库的全部功能。目前使用 Swift 包管理器 和 CocoaPods。
- libplzma.hpp - 纯 C++ 环境的库头文件,必须与 libplzma.h 头文件一起使用。目前用于 npm 原生模块和 Objective-C。
- 在 swift 目录中包含 SDK 的 Swift 部分,可通过 Swift 包管理器 和 CocoaPods 使用,请参阅
安装
部分。 - 在 objc 目录中包含 SDK 的 Objective-C 部分,可通过 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.3.0"))
CocoaPods Podfile (Swift)
use_frameworks!
platform :ios, '11.0'
target '<REPLACE_WITH_YOUR_TARGET>' do
pod 'PLzmaSDK', '1.3.0'
end
CocoaPods Podfile (Objective-C)
use_frameworks!
platform :ios, '9.0'
target '<REPLACE_WITH_YOUR_TARGET>' do
pod 'PLzmaSDK-ObjC', '1.3.0'
end
通过npm的'package.json'
{
"engines": {
"node": ">=13.0.0",
"npm": ">=6.0.0"
},
"dependencies": {
"plzmasdk": "1.3.0"
}
}
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
Compress
创建输出、设置编码器/存档、添加内容、打开和压缩。
该过程包含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 - 2023 Oleh Kulykov [email protected]
以下是对软件及其相关文档文件(“软件”)的副本有权获取的任何人免费许可,准许其在无限制的情况下处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/or 销售软件副本,以及允许向其提供软件的人员进行上述操作,但须遵守以下条件:
上述版权声明和本许可声明应包含在软件所有副本或实质部分的任何副本中。
本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定目的适用性和非侵权性保证。在任何情况下,作者或版权持有人不会因任何主张、损害或其他责任,无论是基于合同、侵权或其他方式,由软件本身或其使用或其他操作引发的,而对作者或版权持有者负责。