# timemachine **Repository Path**: wexiangis/timemachine ## Basic Information - **Project Name**: timemachine - **Description**: 按时间存入,按时间取出,任意数据保存与恢复的工具。 文件格式 + api设计,充分利用文件内存映射,实现高效、安全的文件数据存取。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-09-26 - **Last Updated**: 2024-01-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README * 文件头(2K) ``` #####----- 格式: [offset] [字节数] [定义] -----##### 0000 4 魔数".TME" 2E 54 4D 45 排列,即数值: 0x454D542E 0004 4 文件总大小 0008 2 版本号,默认1.0,即数值 0x0100 0010 2 文件头大小,默认2048 0012 4 预留 0016 256 文件介绍 0272 4 每个FAT表大小,默认2048 0276 4 每个FAT表单元个数,默认 2048/sizeof(uint32_t) = 512 0280 4 每个FAT单元对应数据块大小,默认2048 0284 4 FAT表个数 0288 4 属性表起始FAT单元序号,默认0 0292 4 属性表中,每个属性信息占用字节数,默认32 0296 4 起始属性id,默认为1(从1数起) 0300 4 收录属性个数 0304 4 总览时间表起始FAT单元序号,默认1 0308 4 存储所有属性名称的数据块起始FAT单元序号,默认2 0312 4 预留 0316 4 预留 0320 2 文件创建时间: 年 0322 1 文件创建时间: 月 0323 1 文件创建时间: 日 0324 4 文件创建时间: 当日时间的毫秒值 例如时间 09:30:15.123 对应数值为 9*3600*1000 + 30*60*1000 + 15*1000 + 123 = 34215123 0328 4 文件总时长: 毫秒 0332 4 预留 0336 4 当前空闲fat序号起始 0340 4 预留 0344 4 预留 0348 4 预留 #####----- 内存排列 -----##### [2K,文件头]+[2k,FAT表]+[1M,数据]+[2k,FAT表]+[1M,数据]... ``` * FAT表格 ``` #####----- 简介 -----##### File Allocation Table 用来记录数据块位置和前后链接的表格 #####----- 格式 -----##### 1. 以4字节为一个单元; 2. 每个单元填写一个序号,指向下一个单元位置,形成一个链表; 3. 每个链表反映了一块用户数据的大小,内存中的排列情况以及实际地址位置; 4. 每个单元块对应2k数据量,例如一个链表有3个单元,则用户数据量为2K+2K+(1~2K); 5. 单元填写格式:(按下面bit位定义) [31~30]: 2bit <链表标志> 00 链表继续,后面0x*FFFFFFF空间写入下一个单元序号 01 链表开始,后面0x*FFFFFFF空间写入下一个单元序号 10 链表结束,后面0x*FFFFFFF空间用于记录当前存储块(每块2K)的使用量 (例如占用2个FAT单元,且最后值为0x10,则数据大小为 2048*1+16=2064字节) 11 链表开始&结束(只有1块数据),后面0x*FFFFFFF空间用于记录当前存储块(每块2K)的使用量 [29~28]: 2bit <数据类型> 00 普通数据 01 属性表(文件有且仅有一个) 10 属性名称表(文件有且仅有一个) 11 时间表(文件会有一个总时间表,每个属性也有自己的时间表) [27~00]: 28bit 0x*0000000~0x*FFFFFFF 记录FAT单元序号或者当前存储块(每块2K)的使用量 即单个文件最大数据量约为 0xFFFFFFF*2K ~= 512G [其它情况]: 当数值为0x00000000时,表示该块未使用 [其它说明]: 依据FAT单元序号值范围可知,一个.tme文件最大约为 0xFFFFFFF*2K ~= 512G #####----- 示例 -----##### 01 00 00 40 02 00 00 00 08 04 00 80 05 00 00 40 14 00 00 C0 06 00 00 00 07 00 00 00 03 06 00 80 #####----- 解析 -----##### 1. 上面有3个数据块(链表); 2. 第一个数据块链表是连续的,从 01 00 00 40 到 08 04 00 80 结束,用户数据大小为 2k + 0x408 = 5128字节; 3. 第二个数据块链表发生了跳跃,链表起始 05 00 00 40 没有指向下一单元04,而是指向06,最后在 03 06 00 80 结束,用户数据大小为 2k*2 + 0x603 = 1539字节; 4. 第三个数据块链表只有一个单元块 14 00 00 C0 所以直接标记为链表起始&结束,用户数据大小为 0x14 = 30字节; ``` * 数据: 属性表(整个文件只有1个属性表) ``` #####----- 简介 -----##### 记录所有属性信息的表格,每个表格固定大小64字节,顺序排列 #####----- 格式: [offset] [字节数] [定义] -----##### 0000 4 属性ID,仅低28bit可用,自然累加计数生成 0004 4 父属性ID,仅低28bit可用(0表示没有父属性) 0008 4 数据段的起始FAT序号(0表示还没有数据) 0012 4 时间表的起始FAT序号(0表示还没有数据) 0016 4 属性名称字节数 0020 4 属性名称在名称表中的偏移量(暂未使用) 0024 4 属性内容时间跨度,单位ms 0028 4 属性内容总字节数 0032 32 预留空间(暂时用于属性名称前31字节,用于预览) ... 下一个属性 ``` * 数据: 属性名称表(整个文件只有1个属性名称表) ``` #####----- 简介 -----##### 用于存储属性名称的内存块,实现属性名称长度不受限,名称之间紧挨没有间隔符 ``` * 数据: 时间表(文件有一个总览时间表,每个属性又有自己的时间表) ``` #####----- 简介 -----##### 以时间为顺序,记录什么时间,什么属性,记录了什么; 以4字节为一个单元,按时间顺序存储,发生变动时更新单元 #####----- 单元格式(4字节) -----##### [31~28] 4bit 单元类型 0000 0.数据长度变化 0001 1.属性ID变动 0010 2.数据offset位置变化(所在FAT序号变动或者切换属性时播报一次) 1XXX 8+.时间增量变动(单位:ms) [27~0] 28bit 内容0x*FFFFFFF 类型0: 内容为写入的数据长度 类型1: 内容为属性ID 类型2: 内容为写入数据后的偏移量 类型8+: 内容为时间偏移量,单位:ms,此时可赋值范围是后31bit,最大时差 #####----- 示例 -----##### #####----- 解析 -----##### [其它说明]: 1.时间表的信息是需要上下文配合的(类似数据包需要有个包头才能解析后面的数据), 所以一个正确的数据读取节点,应该是一个[类型1:属性ID变动]的数据; 2.当出现属性ID变动时,应该依次出现[类型1:属性ID变动][类型2:offset变动][类型8:时间变动] ```