如何将含连续5位无符号数的压缩二进制文件读入整数数组
处理连续5位无符号数的二进制文件读取
直接用fread读取会出错,因为fread是按**字节(8位)**为单位读取数据,而你的文件是把5位无符号数连续打包存储的——单个字节里可能包含1个完整的5位数据,或者和相邻字节拼接出完整的5位数据,因此必须手动解析位流来提取每个5位数值。
核心思路
- 先读取整个文件的字节数据到缓冲区(或逐字节读取),维护一个位指针记录当前处理到字节的第几位。
- 每次从当前位置提取5位:如果当前字节剩余位数不足5位,就从下一个字节补够剩余位数。
- 将提取的5位二进制转换成无符号整数,存入目标数组。
- 总有效数的个数为
(文件总字节数 × 8) ÷ 5,不足5位的末尾数据直接丢弃(因为是连续的5位无符号数,不存在不完整的有效数据)。
示例代码(C语言)
#include <stdio.h> #include <stdlib.h> #define BITS_PER_NUMBER 5 int main() { FILE *fp = fopen("your_data.bin", "rb"); if (!fp) { perror("Failed to open file"); return 1; } // 获取文件总大小 fseek(fp, 0, SEEK_END); long file_size = ftell(fp); fseek(fp, 0, SEEK_SET); // 分配缓冲区存储所有字节数据 unsigned char *byte_buffer = malloc(file_size); if (!byte_buffer) { perror("Failed to allocate buffer"); fclose(fp); return 1; } // 读取全部字节到缓冲区 size_t read_bytes = fread(byte_buffer, 1, file_size, fp); if (read_bytes != file_size) { perror("Failed to read full file"); free(byte_buffer); fclose(fp); return 1; } fclose(fp); // 计算可提取的5位无符号数总个数 long total_bits = file_size * 8; long num_count = total_bits / BITS_PER_NUMBER; unsigned int *num_array = malloc(num_count * sizeof(unsigned int)); if (!num_array) { perror("Failed to allocate number array"); free(byte_buffer); return 1; } int current_byte = 0; int current_bit = 0; // 0表示当前字节的最高位,7表示最低位 for (long i = 0; i < num_count; i++) { unsigned int value = 0; int remaining_bits = BITS_PER_NUMBER; while (remaining_bits > 0) { // 当前字节剩余可用位数 int available_bits = 8 - current_bit; // 本次提取的位数:取剩余需要的位数和当前可用位数的较小值 int take = (remaining_bits < available_bits) ? remaining_bits : available_bits; // 生成掩码提取目标位 unsigned char mask = (0xFF >> (8 - take)) << (available_bits - take); unsigned char extracted_bits = (byte_buffer[current_byte] & mask) >> (available_bits - take); // 将提取的位拼接到结果中 value = (value << take) | extracted_bits; remaining_bits -= take; current_bit += take; // 当前字节处理完毕,切换到下一个字节 if (current_bit == 8) { current_byte++; current_bit = 0; } } num_array[i] = value; } // 验证:打印前10个数值(可根据需求修改) for (long i = 0; i < (num_count > 10 ? 10 : num_count); i++) { printf("Num %ld: %u\n", i, num_array[i]); } // 释放内存 free(byte_buffer); free(num_array); return 0; }
为什么你之前的尝试会失败
- 直接用
fread读取得到的是8位字节值,而不是打包的5位数据,自然数值错误。 - 数组末尾的空项是因为你可能按文件字节数来分配数组大小,但实际有效5位数值的个数是
总位数÷5,远小于字节数,导致数组后半部分未被填充。
内容的提问来源于stack exchange,提问作者Timbin
相关产品推荐
相关产品推荐

