文件差分服务设计

news2024/10/1 21:40:38

需求

OTA(Over-The-Air)升级是一种至关重要的技术,用于更新嵌入式设备的固件或软件,以确保设备具备最新功能和修复漏洞。在OTA升级过程中,使用差异算法工具(如bsdiff、hdiffpatch和xdelta3)能够有效减小升级包的大小,从而降低带宽消耗并提高升级效率。以下是对差异算法在OTA升级中的重要性的更详细说明:

  1. 带宽节省:通过使用差异算法,云端可以提取新旧升级包之间的差异数据,生成相对较小的差异包。这意味着只需传输差异包,而不是整个新升级包。这极大地降低了数据传输所需的带宽,尤其对于大型升级包而言。

  2. 成本降低:减少传输数据量不仅有助于带宽节省,还能减少数据传输费用。这对于云端提供OTA服务的成本管理非常关键。

  3. 快速升级:较小的差异包能更快速地下载到设备上,且设备更容易处理和应用差异数据。这减少了升级过程所需的时间,有助于确保用户设备迅速获取最新功能和修复。

  4. 存储空间节省:设备的存储空间是有限的,较小的差异包需要更少的存储空间,对设备而言非常有益。

  5. 版本控制:差异算法还能轻松进行版本控制,确保设备获取正确的升级。

升级流程

OTA升级流程:

  1. 计算差分包:云端根据升级需求,调用差分服务,输入文件 V1(当前版本)和文件 V2(新版本)来计算差分包 PATCH(差异数据)。hdiffpatch 将生成一个相对较小的 PATCH 差分包,其中包含了新版本相对于当前版本的差异信息。

  2. 通知设备下载差分包:云端通知设备有可用的升级。设备收到通知后,开始下载差分包 PATCH。

  3. 应用差分包:设备成功下载差分包 PATCH 后,它使用文件 V1(当前版本)和差分包 PATCH 来还原文件 V2(新版本)。设备内部的 hdiffpatch 工具将应用 PATCH 差异数据到当前版本文件 V1 上,生成新版本文件 V2。这个过程是快速的,因为 PATCH 包是相对较小的,只包含了需要修改的数据。

  4. 安全性检查:设备在应用差分包后,可以进行安全性检查来确保新版本文件 V2 完整和正确。这可以包括校验文件的哈希值或数字签名,以防止潜在的数据损坏或恶意修改。

  5. 更新完成通知:设备在成功应用差分包且通过安全性检查后,通知云端升级完成。云端记录设备已完成升级,以便进行版本跟踪和管理。

通过这一流程,我们能够充分利用 hdiffpatch 差异算法,将升级包的大小减小,降低了升级过程中的带宽需求,同时保持了升级的效率。这对于嵌入式设备的OTA升级是一个优化的、可行的方案。

方案设计

技术路线

  • BsDiff:BsDiff(Binary Software Differential)是一种用于生成二进制文件差异(差异数据)的算法。通常用于比较原始文件和新文件,生成差异文件,然后将差异文件应用到原始文件,生成新文件。BsDiff的核心思想是将二进制文件划分成块,计算块之间的差异,然后将这些差异编码成差异文件。BsDiff算法的目标是生成最小的差异数据,以在生成和应用差异时尽可能减小文件大小并提高效率。它在软件更新、版本控制等领域非常有用,因为它减小升级文件的大小,降低下载和存储成本。

  • hdiffpatch:hdiffpatch 是另一个差异生成和应用工具,专门用于减小文件大小,特别是用于固件和软件的更新。它被设计为高性能、低内存占用的工具,可以生成小差异文件以减小升级包的大小,从而节省带宽和提高升级效率。hdiffpatch的基本原理是将文件划分成块,找到相匹配的块,计算不匹配块之间的差异,将差异数据编码成差异文件,然后使用差异文件来应用差异数据以生成新文件。hdiffpatch强调高性能和低内存占用,适用于嵌入式设备和固件更新等场景。它的主要优势在于生成较小的差异文件,减小升级包的大小,降低带宽消耗,以及节省存储空间。

技术对比

BsDiff 和 hdiffpatch 都是用于生成和应用二进制文件差异的算法,用于减小升级包的大小,从而节省带宽和降低成本。它们有各自的特点和优势,下面对它们进行比较:

BsDiff:

  1. 基本原理:BsDiff 将文件划分成块,找到匹配的块,计算不匹配块之间的差异,然后编码差异文件。差异文件可以应用到原始文件上,生成新文件。

  2. 优势

    • 生成的差异文件通常较小,节省带宽。
    • 被广泛用于软件更新、版本控制等领域。
    • 相对成熟的开源实现可供使用。
  3. 劣势

    • 生成和应用差异的性能可能不如 hdiffpatch。
    • 对于某些文件类型,可能生成较大的差异文件。

hdiffpatch:

  1. 基本原理:hdiffpatch 也将文件划分成块,找到匹配的块,计算不匹配块之间的差异,然后编码差异文件。差异文件可以应用到原始文件上,生成新文件。

  2. 优势

    • 高性能,生成和应用差异的速度较快。
    • 低内存占用,适合嵌入式设备等资源受限的环境。
    • 生成的差异文件通常较小,节省带宽和存储空间。
    • 支持多平台,可在不同操作系统上使用。
  3. 劣势

    • 可能不如 BsDiff 在某些文件类型上表现出色。
    • 开源实现相对较新,可能需要更多的定制和集成工作。

技术选型

考虑到本次方案将面向多种嵌入式设备arm和x86架构,我们决定采用 hdiffpatch 作为差异算法的核心。主要原因如下:

  1. 通用性:hdiffpatch 是一种通用性较强的差异算法,适用于各种嵌入式设备。这意味着我们可以在不同设备上实现统一的OTA升级方案,而不需要为每种设备单独开发和维护不同的差异算法。

  2. 高性能:hdiffpatch 被设计为高性能工具,特别是在生成和应用差异数据时表现出色。对于无人车等对性能要求较高的设备,这一特点尤为重要,因为它可以加速升级过程,降低用户设备的升级时间。

  3. 低内存占用:嵌入式设备通常拥有有限的内存资源,hdiffpatch 的低内存占用使其非常适合这些资源受限的环境。这将有助于确保升级过程不会占用过多内存,从而不影响设备的正常运行。

  4. 小差异文件:hdiffpatch 生成的差异文件通常较小,减小了升级包的大小。这对于需要在有限带宽下进行OTA升级的设备(例如无人车)非常重要。

  5. 多平台支持:hdiffpatch 支持多种操作系统和平台,这意味着可以在不同嵌入式设备上使用,无论其运行的操作系统是什么。这种灵活性将简化方案的部署和维护。

  6. 版本控制:差异算法允许进行版本控制,确保设备得到正确的升级。这在嵌入式设备的OTA升级中至关重要,因为需要确保安全性和正确性。

因此,通过采用 hdiffpatch 差异算法,我们可以实现一种通用、高性能、低内存占用的OTA升级方案,适用于多种嵌入式设备。这将有助于确保设备快速、安全地获得最新的功能和修复,同时减小了部署和维护成本,提高了升级效率。

基本测试

升级示意图

下图展示了通过两种方式,将图1升级到图片2升级的过程
在这里插入图片描述

极端情况测试
  • 文件完全不一致

    在文件完全不一致的情况下,采用2张完全不一样的图片进行测试,1.jpg2.jpg 内容完全不一致,普通升级需要传输 596KB 数据,差分升级需要传输 488KB 数据。

    文件类型普通升级差分升级
    1.jpg629 KB629 KB
    2.jpg596 KB0 KB
    PATCHA文件0 KB488 KB
  • 文件增量

    在文件增量情况下,采用2份txt文件进行测试,2.txt1.txt 基础上进行了字符串增加,普通升级需要传输 119KB 数据,差分升级仅需要传输 0.11KB 数据。

    文件类型普通升级差分升级
    1.txt11.9 KB11.9 KB
    2.txt119 KB0 KB
    PATCHA文件0 KB0.11KB

参考资料

  • 项目地址

    https://github.com/sisong/HDiffPatch/releases/tag/v4.6.7

  • SDK

    linux64

    arm64

    android

    windows64

    source code

  • java参考代码

    HDiffPatch 的官方实现是基于 C/C++ 的库。虽然它没有官方的 Java 实现,但你可以通过 Java 的 JNI(Java Native Interface)机制来调用 C/C++ 库中的函数。以下是一个简单的示例,演示如何使用 JNI 在 Java 中调用 HDiffPatch 的 C/C++ 函数。

    首先,需要编写一个 Java 类,用于加载 HDiffPatch 动态链接库并定义与 C/C++ 函数的映射。以下是一个示例 Java 类:

    import java.io.*;
    import java.nio.file.*;
    import java.nio.ByteBuffer;
    
    public class HDiffPatch {
    	static {
    		System.loadLibrary("hdiff");  // 请根据你的库名称进行修改
    	}
    
    	// JNI 声明:生成差异数据
    	private static native int createDiff(byte[] oldData, byte[] newData, byte[] diffData);
    
    	// JNI 声明:应用差异数据
    	private static native int applyDiff(byte[] oldData, byte[] diffData, byte[] newData);
    
    	public static void generateDiffData(String oldFilePath, String newFilePath, String diffFilePath) {
    		try {
    			byte[] oldData = Files.readAllBytes(Paths.get(oldFilePath));
    			byte[] newData = Files.readAllBytes(Paths.get(newFilePath));
    
    			byte[] diffData = new byte[Math.max(oldData.length, newData.length)]; // 设置差异数据的大小
    
    			int result = createDiff(oldData, newData, diffData);
    
    			if (result == 0) {
    				Files.write(Paths.get(diffFilePath), diffData);
    				System.out.println("差异数据生成成功!");
    			} else {
    				System.out.println("差异数据生成失败。");
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public static void applyDiffData(String oldFilePath, String diffFilePath, String newFilePath) {
    		try {
    			byte[] oldData = Files.readAllBytes(Paths.get(oldFilePath));
    			byte[] diffData = Files.readAllBytes(Paths.get(diffFilePath));
    
    			byte[] newData = new byte[oldData.length + diffData.length]; // 设置新文件的最大可能大小
    
    			int result = applyDiff(oldData, diffData, newData);
    
    			if (result == 0) {
    				Files.write(Paths.get(newFilePath), newData);
    				System.out.println("差异数据应用成功!");
    			} else {
    				System.out.println("差异数据应用失败。");
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String[] args) {
    		String oldFile = "old.bin";
    		String newFile = "new.bin";
    		String diffFile = "diff.bin";
    		String restoredFile = "restored.bin";
    
    		// 生成差异数据
    		generateDiffData(oldFile, newFile, diffFile);
    
    		// 应用差异数据
    		applyDiffData(oldFile, diffFile, restoredFile);
    	}
    }
    

    上述示例代码假定你已经编译了 HDiffPatch 的 C/C++ 动态链接库(.so 文件),并将其放在正确的位置。你需要根据你的库文件名和路径进行修改。请注意,这是一个简单的示例,你可能需要根据你的项目需求和环境进行更复杂的设置和错误处理。

  • c++参考代码

    下面是一个基本的 C++ 示例,展示如何使用 HDiffPatch 来生成差异数据和应用差异数据以还原文件。请注意,HDiffPatch 需要在项目中添加相关的头文件和链接到库文件。

    #include <iostream>
    #include <vector>
    #include "HDiff/diff.h"  // 请根据你的项目实际情况包含正确的头文件
    
    int main() {
    	// 原始文件数据
    	std::vector<uint8_t> oldData = {1, 2, 3, 4, 5};
    
    	// 新文件数据
    	std::vector<uint8_t> newData = {1, 2, 3, 9, 5};  // 更改第四个字节的值
    
    	// 差异数据存储
    	std::vector<uint8_t> diffData;
    
    	// 生成差异数据
    	int result = create_diff(oldData.data(), oldData.size(), newData.data(), newData.size(), diffData);
    
    	if (result == 0) {
    		// 差异数据生成成功,你可以保存它或传输给其他设备
    		std::cout << "差异数据生成成功!" << std::endl;
    	} else {
    		std::cout << "差异数据生成失败。" << std::endl;
    		return 1;
    	}
    
    	// 还原新文件
    	std::vector<uint8_t> restoredData;
    	restoredData.resize(oldData.size() + diffData.size());
    
    	result = apply_diff(oldData.data(), oldData.size(), diffData.data(), diffData.size(), restoredData.data(), restoredData.size());
    
    	if (result == 0) {
    		// 新文件已还原,你可以保存它
    		std::cout << "新文件还原成功!" << std::endl;
    	} else {
    		std::cout << "新文件还原失败。" << std::endl;
    		return 1;
    	}
    
    	return 0;
    }
    

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

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

相关文章

eNSP-直连通信实验

实验拓扑&#xff1a; 实验需求&#xff1a; 1. 按照图中的设备名称&#xff0c;配置各设备名称 2. 按照图中的IP地址规划&#xff0c;配置IP地址 3. 测试R1与R2是否能ping通 4. 测试R2与R3是否能ping通 5. 测试R1与R3是否能ping通 实验步骤&#xff1a; 1. 加入设备&…

2023亚太杯数学建模C题思路 - 我国新能源电动汽车的发展趋势

1 赛题 问题C 我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源( 非常规汽车燃料指汽油、柴油以外的燃料&#xff09;&#xff0c;将先进技术进行汽车动力控制和驱动相结 合的汽车。新能源汽车主要包括四种类型&#x…

应用带通滤波器进行划痕检测

案例要求&#xff1a; 图为HALCON中的例图“surface_scratch”&#xff0c;请提取出图中的划痕。 案例分析&#xff1a; 图中明亮程度不一&#xff0c;划痕颜色较淡&#xff0c;因此不能用灰度BLOB分析的方法提取出目标区域。因此&#xff0c;先构造一个带通滤波器&#xff0…

Linux编程 文件操作 creat open

文件描述符 文件描述符在形式上是一个非负整数。实际上&#xff0c;它是一个索引值&#xff0c;指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时&#xff0c;内核向进程返回一个文件描述符。 启动一个进程之后&#xff0c;…

3.OpenFeign的使用

OpenFeign 文章目录 OpenFeign一. 什么是OpenFeign二. OpenFeign基础使用1.添加依赖2.配置Nacos配置信息3.在项目中开启OpenFeign4.编写OpenFeign调用代码5.调用OpenFeign接口 三. OpenFeign内置的超时重试机制1.配置超时重试2.覆盖Retryer对象 四.自定义超时重试机制1.自定义超…

vue3-生命周期

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-生命周期 目录 vue3生命周期 vue3生命周期钩子 1.1 onMounted() 1.2 onUpdated() 1.3 onU…

Airtest结合Poco对控件实施精准截图,学起来!

1.前言 最近在Q群内发现有个小伙伴提出了一个很有趣的脚本需求&#xff0c;想要实现“通过选择器获取到了控件&#xff0c;然后截图这个控件范围”&#xff0c;根据我们的Airtest的局部截图接口以及poco控件的属性查询接口是可以很快实现的~ 2.接口查找 首先我们需要知道我们…

什么软件可以做报表?

报表在现代企业和组织中扮演着重要角色。它们是数据汇总、分析和展示的重要工具&#xff0c;为管理层和决策者提供洞察和指导。但是&#xff0c;报表的制作并非易事。使用Excel或手写代码开发报表可能会带来一系列痛点&#xff0c;而现代化的解决方案——比如VeryReport报表软件…

分布式锁之传统锁回顾(一)

1. 传统锁回顾 1.1. 从减库存聊起 多线程并发安全问题最典型的代表就是超卖现象 库存在并发量较大情况下很容易发生超卖现象&#xff0c;一旦发生超卖现象&#xff0c;就会出现多成交了订单而发不了货的情况。 场景&#xff1a; 商品S库存余量为5时&#xff0c;用户A和B同…

智能导视电子指路牌是什么?

SVIP-3800系列智能电子指路牌也称智慧指路灯杆&#xff0c;智能指路牌&#xff0c;导航立柱&#xff0c;多功能指示牌&#xff0c;多功能路标&#xff0c;智能指路机器人&#xff0c;智能导视指路牌&#xff0c;问路导航机器人&#xff0c;智能路牌&#xff0c;叁仟智慧路牌、智…

电商数据采集|电商API接口接入|从京东平台获取商品SKU 主图 价格 详情数据

在进行API开发过程中&#xff0c;数据异常常常令人头痛。我们的API开车软件经过精心设计和测试&#xff0c;能够准确识别并及时处理各类数据异常。拥有稳定的运行环境&#xff0c;保障了您的开发进程不受干扰&#xff0c;让您的工作更加顺畅高效。 京东获得JD商品详情 API 返…

AI助力钢铁产业数字化,python基于YOLOv5开发构建钢铁产业产品智能自动化检测识别系统

AI为工业产业智能化数字化赋能早已不是什么新鲜事&#xff0c;越来越多的行业和领域开始更大范围去拥抱AI&#xff0c;享受科技带来的变革力量&#xff0c;在我们之前的文章中也有很多相关领域项目的实践经历&#xff0c;本文的核心目标就是想要基于钢铁领域产品数据来开发构建…

VirtualBox下win主机如何访问linux虚拟机文件夹

目录 ​编辑 方法1&#xff1a;通过VirtualBox自带的共享文件夹&#xff08;Win->linux&#xff09; 方法2&#xff1a;通过Samba方法本地网络访问(Linux->win) 我使用的VirtualBox版本为7.0.4,主机是Window系统&#xff0c;虚拟机是Linux系统 方法1&#xff1a;通过Vir…

易点易动设备管理系统提升设备能耗管理和设备状态监控效率

如今&#xff0c;能源效率和设备状态监控对于企业来说变得越发重要。传统的设备管理方式往往存在能耗浪费和难以实时监控设备状态的问题。为了解决这些问题&#xff0c;易点易动设备管理系统应运而生。本文将介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何通过它提…

深度学习之六(自编码器--Autoencoder)

概念 自编码器(Autoencoder)是一种神经网络架构,用于无监督学习和数据的降维表示。它由两部分组成:编码器(Encoder)和解码器(Decoder)。 结构: 编码器(Encoder): 接收输入数据并将其压缩为潜在表示(latent representation),通常比输入数据的维度要低。编码器的…

Sam Altman回归OpenAI,新董事会成员曝光!

11月22日下午&#xff0c;OpenAI在社交平台宣布&#xff0c;在原则上已达成协议&#xff0c;让 Sam Altman重返 OpenAI担任首席执行官&#xff0c;并重组董事会。稍后会公布更详细的内容。 初始董事会成员包括前Salesforce联合首席执行官Bret Taylor&#xff08;担任主席&…

【AI读论文】AutoML的8年回顾:分类、综述与趋势

论文标题&#xff1a;Eight years of AutoML: categorisation, review and trends 论文链接&#xff1a;https://link.springer.com/article/10.1007/s10115-023-01935-1 本文主要围绕自动机器学习&#xff08;AutoML&#xff09;展开了系统性的文献综述&#xff0c;总结了该领…

德迅云安全-德迅卫士:保障您的主机安全

主机安全是指保证主机在数据存储和处理的保密性、完整性、可用性&#xff0c;包括硬件、固件、系统软件的自身安全&#xff0c;以及一系列附加的安全技术和安全管理措施。 为什么要主机安全&#xff1f; 服务器一旦被黑客入侵&#xff0c;个人和企业面临以下安全风险&#xff…

基于springboot实现家政服务管理平台项目【项目源码+论文说明】

摘要 随着家政服务行业的不断发展&#xff0c;家政服务在现实生活中的使用和普及&#xff0c;家政服务行业成为近年内出现的一个新行业&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计家政服务管理平台的目的就是借助计算机让复杂的销售操作变简单&#xff0c;…

unity Toggle,初始时默认不选中,若选中则不可取消选中。不写码实现其效果

实现效果&#xff1a; 初始默认时&#xff1a; 选中时&#xff1a; 零代码实现&#xff1a; 步骤1 步骤2 步骤3