标签归档:encode

二进制文件跟普通文本文件的区别

作者: dplord, 访问量 1768





任何文件都可以划分为二进制文件(binary file)跟文本文件(text file), 两种文件表面上看起来显示,但是两种文件编码数据的方式却有差异。两种文件都是用一系列的字节编码数据,在文本文件中,所编码的字节就是代表文本文件的内容,而二进制文件的编码,却代表自定义的数据格式,需要特殊的去decode文件内容。下面就用『ab12\n3』为代表写入两种文件,读取看看差异。(\n 是换行符)

写程序如下:

#include <stdio.h>
#include <string.h>

int main() {
	FILE *fp = fopen("data.text", "w+");
	FILE *fp1 = fopen("data.bin", "wb+");
	
	
	if((fp == NULL) || (fp1 == NULL)) 
	{
		fprintf(stderr, "can not open file...");
		return -1;
	}
		
	const char *str = "ab12\n3";
	int len = strlen(str);
	fwrite(str, len, 1, fp);
		
	const char *str1 = "ab";
	int a = 12;
	const char *str2 = "\n";
	int b = 3;
	int len1 = strlen(str1);
	int len2 = strlen(str2);
	
	fwrite(str1, len1, 1, fp1);
	fwrite(&a, 1, 1, fp1);
	fwrite(str2, len2, 1, fp1);
	fwrite(&b, 1, 1, fp1);
	
	fclose(fp);
	fclose(fp1);
	return 0;
}

查看文件大小,  如下

➜  ~ ll -h data.text data.bin
-rw-r--r--  1 dengpan  staff     5B  3 14 01:38 data.bin
-rw-r--r--  1 dengpan  staff     6B  3 14 01:38 data.text
➜  ~ hexdump data.text
0000000 61 62 31 32 0a 33
0000006
➜  ~ hexdump data.bin
0000000 61 62 0c 0a 03
0000005

二进制文件data.bin是5bit, 文本文件data.text是6bit。其中文本文件data.text中的6个bit,分别对应a、b、1、2、\n、3。其中二进制文件data.bin里面的5个bit分别对应a、b、12、\n、3。

其中data.text就是其中的文本字符串的anscii吗,一个字符一个字符对应的。具体个参照ascii-table。文本编辑器打开data.text会换行,是因为碰到了换行符0a,编辑器会自动做换行处理的。

二进制文件的每一个bit放什么数据完全可以自己控制,可以放int、short、char等等,也可以放struct数据。当时解析二进制file的时候,需要知道解析规则,不然也不可读。以下是data.bin根据写的顺序写的读出来输出内容的解析代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	FILE *fp = fopen("data.bin", "rb+");
	if(fp == NULL) 
	{
		fprintf(stderr, "can not open file...");
		return -1;
	}
	
	int len_a = 2;
	char *a = malloc(len_a);
	int num1 = 0;
	int len_b = 1;
	char *b = malloc(len_b);
	int num2 = 0;
	
	fread(a, len_a, 1, fp);
	fread(&num1, 1, 1, fp);
	fread(b, len_b, 1, fp);
	fread(&num2, 1, 1, fp);

	printf("%s%d%s%d\n", a, num1, b, num2);
	fclose(fp);
	return 0;
}

其实文本文件本身就是一个特殊的binary file, 只不过是按照字符串内容,依次按字节写内容而已。二进制文件是按照自己的编码格式来的,常见的二进制文件比如图片、文档、视频,遵循一定的约定,通常是约定头部字节等于一些固定开头的值,各个文件约定也不尽相同,比如jpg的文件的头4个字节是固定的FF D8 FF E0 或者 FF D8 FF E1 或者 FF D8 FF E8, png的头8个字节是89 50 4E 47 0D 0A 1A 0A。用hexdump可以查看一个文件的hex内容。比如:

QQ20160314-1@2x

具体的查看每种文件的头部字节约定可以查看,File signatures网站