开发中遇到存储图片文件于数据库这样的需求。
我们知道文件本身就是一份二进制数据,不同类型的文件只是编码形式不同,对应的解读形式不同,无论txt文件、jpg文件亦或是mp4文件,本质上都是0和1组成的。而在C++中我们可以通过字节流来读写文件,也就是说我们可以把文件读入char数组中,也可以将char数组中的数据写入为文件。
开发中需要将图片存在数据库中,每个文件几KB,想将之存在数据库表的varchar类型中。大小不是问题,大的话就以text类型存储。关键是,C++读取的文件字节流的char数组是不能直接存储的,因为里面会含有很多‘ ’。如果按照字符串来理解,就是结束符了。那样一来存的内容就不完整了。
所以需要将文件字节流的char数组 转化为二进制字符串,再存储数据库。
从数据库读取后,再转化回文件字节流的char数组。
每一个char,其实就是一个字节,也就是8bit,每个bit是0或者1。我要做的就是读取每一位,将之转化为字符的'0'或者'1',再存储。
所以如果原本是N字节的文件,转化后大小为N*8。
下面是我文件字节流与二进制字符串相互转换的测试程序,参考了几篇文章,里面的程序我略有修改:
http://blog.csdn.net/k346k346/article/details/52170623
http://blog.csdn.net/pointer_y/article/details/51525679
将一个名为timg.jpg的文件,放在程序目录下,程序会将之读取,转化为二进制字符串,然后再转化回去,写入为文件timg2.jpg。
运行结束后会生成一个timg2.jpg,且和timg.jpg一模一样。
该程序还会作 字符串转化的测试,效果为:
#include "stdafx.h" #include "iostream" #include "string.h" #include <fstream> #include <assert.h> using namespace std; #define P1LEN 10013 #define P2LEN 80104 /** * 设置一个字符第n位bit值 * 2018-02-06 */ int bit_set(unsigned char *p_data, unsigned char position, int flag) { int i = 0; assert(p_data); if (position > 8 || position < 1 || (flag != 0 && flag != 1)) return -1; if (flag != (*p_data >> (position - 1) & 1)) *p_data ^= 1 << (position - 1); return 0; } /** * 字符数组 与 二进制字符串 相互转化 * 2018-02-06 */ int char_array_2_binary_str(char ch_buf[],int ch_len,char binary_char_buf[],int binary_char_len,int type){ if(type!=0&&type!=1) return -1; //字节流转二进制字符流 if(type==0){ if(binary_char_len < 8*ch_len) return -1; int char_buf_index=0; for(int i=0;i<ch_len;++i){ for(int j=7;j>=0;--j){ if(ch_buf[i]>>j&0x1) binary_char_buf[char_buf_index++]='1'; else binary_char_buf[char_buf_index++]='0'; } } return 0; } if (type == 1) { if(8*ch_len < binary_char_len) return -1; char tmp_str[9]=""; int ret_buf_index=0; for(int i=0;i<binary_char_len;i=i+8){ strncpy(tmp_str, binary_char_buf+i, 8); for(int j=0; j<8; ++j){ if (tmp_str[j] == '0') bit_set((unsigned char *)ch_buf+ret_buf_index, 8-j, 0); if (tmp_str[j] == '1') bit_set((unsigned char *)ch_buf+ret_buf_index, 8-j, 1); } ret_buf_index++; } return 0; } } int _tmain(int argc, _TCHAR* argv[]) { ////////首先,字符串转换测试//////////////// char* txt = "异度神剑"; cout << "原始字符串为:"<< txt << endl << endl; char binary_txt_buf[65]; char_array_2_binary_str(txt,8,binary_txt_buf,64,0); binary_txt_buf[64] = '