压缩和归档库-LZ4介绍

news2025/1/10 20:58:37

1.简介

LZ4是一种快速的压缩算法,提供压缩和解压缩的速度,而牺牲了压缩率。它被设计用于快速的数据压缩和解压缩,特别是用于数据存储和传输。LZ4通常用于需要高速数据处理的场景,如数据库、日志文件处理和实时数据传输。

LZ4的特点是压缩和解压缩速度快,但压缩率不如其他一些压缩算法(如gzip或zstd)。

LZ4的工作原理是基于字典的压缩,它查找数据中的重复字符串,并用较短的形式来表示这些重复的部分。这种算法非常适合于有大量重复数据的情况。

以下是和其他压缩算法的比较:
在这里插入图片描述

2.环境搭建

下载地址:https://github.com/lz4/lz4/tree/v1.9.4
解压缩文件之后,进入到编译目录。
在这里插入图片描述
双击lz4.sln打开工程。
这里编译静态库,将lz4file.c和lz4file.h添加进工程中,编译好后生成liblz4_static.lib静态库。
在这里插入图片描述
拷贝include文件和生成的liblz4_static.lib静态库到我们的demo工程下。
在这里插入图片描述

最后在visual studio中添加include目录 和 lib目录即可。
配置visual studio环境,具体参考请看Jsoncpp介绍。

3.示例

压缩/解压缩文件

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

extern "C"
{
#include "lz4.h"
#include "lz4file.h"
}


#define CHUNK_SIZE (16*1024)

static size_t get_file_size(char *filename)
{
	struct stat statbuf;

	if (filename == NULL) {
		return 0;
	}

	if (stat(filename, &statbuf)) {
		return 0;
	}

	return statbuf.st_size;
}

static int compress_file(FILE* f_in, FILE* f_out)
{
	assert(f_in != NULL); assert(f_out != NULL);

	LZ4F_errorCode_t ret = LZ4F_OK_NoError;
	size_t len;
	LZ4_writeFile_t* lz4fWrite;
	void* const buf = malloc(CHUNK_SIZE);
	if (!buf) {
		printf("error: memory allocation failed \n");
	}

	/* Of course, you can also use prefsPtr to
	 * set the parameters of the compressed file
	 * NULL is use default
	 */
	ret = LZ4F_writeOpen(&lz4fWrite, f_out, NULL);
	if (LZ4F_isError(ret)) {
		printf("LZ4F_writeOpen error: %s\n", LZ4F_getErrorName(ret));
		free(buf);
		return 1;
	}

	while (1) {
		len = fread(buf, 1, CHUNK_SIZE, f_in);

		if (ferror(f_in)) {
			printf("fread error\n");
			goto out;
		}

		/* nothing to read */
		if (len == 0) {
			break;
		}

		ret = LZ4F_write(lz4fWrite, buf, len);
		if (LZ4F_isError(ret)) {
			printf("LZ4F_write: %s\n", LZ4F_getErrorName(ret));
			goto out;
		}
	}

out:
	free(buf);
	if (LZ4F_isError(LZ4F_writeClose(lz4fWrite))) {
		printf("LZ4F_writeClose: %s\n", LZ4F_getErrorName(ret));
		return 1;
	}

	return 0;
}

static int decompress_file(FILE* f_in, FILE* f_out)
{
	assert(f_in != NULL); assert(f_out != NULL);

	LZ4F_errorCode_t ret = LZ4F_OK_NoError;
	LZ4_readFile_t* lz4fRead;
	void* const buf = malloc(CHUNK_SIZE);
	if (!buf) {
		printf("error: memory allocation failed \n");
	}

	ret = LZ4F_readOpen(&lz4fRead, f_in);
	if (LZ4F_isError(ret)) {
		printf("LZ4F_readOpen error: %s\n", LZ4F_getErrorName(ret));
		free(buf);
		return 1;
	}

	while (1) {
		ret = LZ4F_read(lz4fRead, buf, CHUNK_SIZE);
		if (LZ4F_isError(ret)) {
			printf("LZ4F_read error: %s\n", LZ4F_getErrorName(ret));
			goto out;
		}

		/* nothing to read */
		if (ret == 0) {
			break;
		}

		if (fwrite(buf, 1, ret, f_out) != ret) {
			printf("write error!\n");
			goto out;
		}
	}

out:
	free(buf);
	if (LZ4F_isError(LZ4F_readClose(lz4fRead))) {
		printf("LZ4F_readClose: %s\n", LZ4F_getErrorName(ret));
		return 1;
	}

	if (ret) {
		return 1;
	}

	return 0;
}

int compareFiles(FILE* fp0, FILE* fp1)
{
	int result = 0;

	while (result == 0) {
		char b0[1024];
		char b1[1024];
		size_t const r0 = fread(b0, 1, sizeof(b0), fp0);
		size_t const r1 = fread(b1, 1, sizeof(b1), fp1);

		result = (r0 != r1);
		if (!r0 || !r1) break;
		if (!result) result = memcmp(b0, b1, r0);
	}

	return result;
}

int main(int argc, const char **argv) 
{
	char inpFilename[256] = { 0 };
	char lz4Filename[256] = { 0 };
	char decFilename[256] = { 0 };

	if (argc < 2) {
		printf("Please specify input filename\n");
		return 0;
	}

	snprintf(inpFilename, 256, "%s", argv[1]);
	snprintf(lz4Filename, 256, "%s.lz4", argv[1]);
	snprintf(decFilename, 256, "%s.lz4.dec", argv[1]);

	printf("inp = [%s]\n", inpFilename);
	printf("lz4 = [%s]\n", lz4Filename);
	printf("dec = [%s]\n", decFilename);

	/* compress */
	{  
	FILE* const inpFp = fopen(inpFilename, "rb");
	FILE* const outFp = fopen(lz4Filename, "wb");
	printf("compress : %s -> %s\n", inpFilename, lz4Filename);
	LZ4F_errorCode_t ret = compress_file(inpFp, outFp);
	fclose(inpFp);
	fclose(outFp);

	if (ret) {
		printf("compression error: %s\n", LZ4F_getErrorName(ret));
		return 1;
	}

	printf("%s: %zu → %zu bytes, %.1f%%\n",
		inpFilename,
		get_file_size(inpFilename),
		get_file_size(lz4Filename), /* might overflow is size_t is 32 bits and size_{in,out} > 4 GB */
		(double)get_file_size(lz4Filename) / get_file_size(inpFilename) * 100);

	printf("compress : done\n");
	}

	/* decompress */
	{
		FILE* const inpFp = fopen(lz4Filename, "rb");
		FILE* const outFp = fopen(decFilename, "wb");

		printf("decompress : %s -> %s\n", lz4Filename, decFilename);
		LZ4F_errorCode_t ret = decompress_file(inpFp, outFp);

		fclose(outFp);
		fclose(inpFp);

		if (ret) {
			printf("compression error: %s\n", LZ4F_getErrorName(ret));
			return 1;
		}

		printf("decompress : done\n");
	}

	/* verify */
	{   FILE* const inpFp = fopen(inpFilename, "rb");
	FILE* const decFp = fopen(decFilename, "rb");

	printf("verify : %s <-> %s\n", inpFilename, decFilename);
	int const cmp = compareFiles(inpFp, decFp);

	fclose(decFp);
	fclose(inpFp);

	if (cmp) {
		printf("corruption detected : decompressed file differs from original\n");
		return cmp;
	}

	printf("verify : OK\n");
	}
	return 0;
}

生成可执行程序,添加两个参数。运行效果如下:
在这里插入图片描述

4.更多参考

libVLC 专栏介绍-CSDN博客

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍_qt opengl视频播放器-CSDN博客

QCharts -1.概述-CSDN博客

Zlib介绍

压缩和归档库-miniz介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1656900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode例题讲解:快乐数

编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&#xff0c…

C++青少年简明教程:基础知识

C青少年简明教程&#xff1a;基础知识 电脑程序设计&#xff08;Computer programming&#xff09;&#xff0c;或称程序设计&#xff08;programming&#xff09;&#xff0c;是给出解决特定问题程序的过程&#xff0c;程序设计往往以某种程序设计语言为工具&#xff0c;给出这…

每周一算法:传递闭包

题目描述 不等式排序 给定 n n n个变量和 m m m个不等式。其中 n n n小于等于 26 26 26&#xff0c;变量分别用前 n n n 的大写英文字母表示。 不等式之间具有传递性&#xff0c;即若 A > B A>B A>B 且 B > C B>C B>C&#xff0c;则 A > C A>C …

音转文工具,9.8k star! 【送源码】

我们经常会遇到将音频转为文字的情况&#xff0c;比如在开会时录音的会议纪要、上课时录下的老师讲课内容。虽然网上也有一些在线的工具可以将音频转为文字&#xff0c;但是考虑到数据安全和费用问题&#xff0c;使用起来也不是很方便。 今天了不起给大家介绍一款开源工具——…

存储或读取时转换JSON数据

一、 数据库类型 二、使用Hutool工具 存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题&#xff1a; 原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject 三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器 package …

javaMail快速部署——发邮件喽~

目录 功能阐述 前序步骤 &#xff08;1&#xff09;到QQ邮箱中获取到授权码 代码实现 坑 今天在写一个修改密码的功能的时候要用到邮箱的发送&#xff0c;然后因为这个项目比较老旧了&#xff0c;采用的是javaWeb和jsp的配置&#xff0c;对于我只使用过springBoot整合的ja…

进一步分析并彻底解决 Flink container exit 143 问题

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

ASP.NET信息安全研究所设备管理系统的设计与实现

摘 要 以研究所的设备管理系统为背景&#xff0c;以研究所设备管理模式为研究对象&#xff0c;开发了设备管理系统。设备管理系统是设备管理与计算机技术相结合的产物&#xff0c;根据系统的功能需求分析与定义的数据模式&#xff0c;分析了应用程序的主要功能和系统实现的主…

最佳实践 | 八爪鱼采集器如何用PartnerShare做全民分销?

在数字化时代&#xff0c;数据采集和分析已经成为企业运营和决策的重要一环。八爪鱼采集器作为一款领先的SaaS产品&#xff0c;凭借其强大的数据采集和处理能力&#xff0c;成为了众多企业和个人用户的心头好。为了进一步拓展市场份额&#xff0c;提升品牌影响力&#xff0c;八…

nature《自然》期刊文献怎么在家查看下载

nature《自然》期刊我们都知道&#xff0c;是世界上历史悠久的、最有名望的科学杂志之一。下载该期刊文献是需要使用权限的&#xff0c;如果你没有nature《自然》期刊的资源&#xff0c;又该如何获取呢&#xff1f;请看本文的经验分享。 一、先百度“文献党下载器” 在文献党下…

PSCA电源管理软件栈示例

安全之安全(security)博客目录导读 目录 1、移动通讯系统 2、基础设施系统 本博客就PSCA电源管理软件栈进行举例&#xff0c;主要以移动通讯系统和基础设施系统为例来说明。 1、移动通讯系统 图3.4显示了一个可以在基于Linux的移动设备中实现的电源管理堆栈示例。 在Linux…

在uniapp中如何安装axios并解决跨域问题

目录 1、安装axios 2、导入 3、使用&#xff08;发请求&#xff09; 2.解决跨域问题 1.为什么要解决跨域问题&#xff1f; 2.前端如何解决跨域问题&#xff1f; 1、安装axios npm install axios 2、导入 在main.js中导入使用 import axios from axios; // 创建一个名…

【C++】STL-list模拟实现

目录 1、本次需要实现的3个类即接口总览 2、list的模拟实现 2.1 链表结点的设置以及初始化 2.2 链表的迭代器 2.3 容量接口及默认成员函数 1、本次需要实现的3个类即接口总览 #pragma once #include<iostream> #include<assert.h> using namespace std; templ…

机器学习算法之KNN分类算法【附python实现代码!可运行】

一、简介 在机器学习中&#xff0c;KNN&#xff08;k-Nearest Neighbors&#xff09;分类算法是一种简单且有效的监督学习算法&#xff0c;主要用于分类问题。KNN算法的基本思想是&#xff1a;在特征空间中&#xff0c;如果一个样本在特征空间中的k个最相邻的样本中的大多数属…

每日Attention学习5——Multi-Scale Channel Attention Module

模块出处 [link] [code] [WACV 21] Attentional Feature Fusion 模块名称 Multi-Scale Channel Attention Module (MS-CAM) 模块作用 通道注意力 模块结构 模块代码 import torch import torch.nn as nnclass MS_CAM(nn.Module):def __init__(self, channels64, r4):super(…

Android NDK开发——Android Studio 3.5.2安装与配置踩坑

Android NDK开发——Android Studio 3.5.2安装与配置踩坑 一、Android Studio下载二、配置踩坑报错1&#xff1a;Failed to install the following Android SDK packages as some licences have not been accepted报错2&#xff1a;No toolchains found in the NDK toolchains …

【全开源】Java上门洗车小程序源码上门洗车APP 小程序源码支持二次开发6.0

功能特点&#xff1a; 跨界创新&#xff1a;融入科技元素&#xff0c;借助移动互联网快速发展&#xff0c;将科技引入到传统洗车业中。 科技赋能&#xff1a;具有智能化的特点&#xff0c;用户可以根据自身的需求选择不同的洗车项目和服务&#xff0c;包括洗车的时间、地点和服…

滥用 Kubernetes 资源登上月球

Sysdig 2024 年云原生安全和使用报告强调了不断变化的威胁形势&#xff0c;但更重要的是&#xff0c;随着容器和 Kubernetes 等云原生技术的采用不断增加&#xff0c;并非所有组织都遵循最佳实践。当攻击者在 Kubernetes 等操作中利用容器来利用资源时&#xff0c;这最终会给攻…

【stomp 实战】spring websocket 接收消息源码分析

后台消息的发送过程&#xff0c;我们通过spring websocket用户消息发送源码分析已经了解了。我们再来分析一下后端接收消息的过程。这个过程和后端发送消息过程有点类似。 前端发送消息 前端发送消息给服务端的示例如下&#xff1a; 发送给目的/app/echo一个消息。 //主动发…

线程安全的概念及原因

1.观察线程不安全 public class ThreadDemo {static class Counter {public int count 0;void increase() {count;}}public static void main(String[] args) throws InterruptedException {final Counter counter new Counter();Thread t1 new Thread(() -> {for (int …