有时候我们需要将基本数据类型转化为字节,以便写入文件,然后必要时还需要将这些字节读出来。有人说,为啥不把数字直接存进文件呢?比如:100,000,000,我们直接存数字明文到文件那就是9个字符(char,9*8bit=9Byte),如果存int就是4Byte,差了一倍多,所以这样存不划算。
有三种方法:
1. 与运算,该方法适用于整数类型
思路就是利用0xff取与最低位,可将高位全置为0,而保留最地位,所以这样我们能得到整数的每一位的字节值(8bit=1Byte)
string toBytes( unsigned int x ) {
std::size_t size = sizeof(x);
std::size_t cnt = size;
string _return(size,0);
while( cnt-- ) {
unsigned char byte = (unsigned char)((x>>((size-1-cnt)*8)) & 0xff);
_return[ cnt ] = byte;
}
return _return;
}
unsigned int getUInt( const string & x ) {
unsigned int _return = 0;
for( std::size_t i = 0; i < x.size(); ++i ) {
_return += static_cast<unsigned char>( x[x.size()-1-i]) *static_cast<unsigned int>(pow( 256, i ));
}
return _return;
}
2. 指针逐位读取字节
该思路就是我们可以把指针强制转化为char * ,因为指针本身就是一个长整型的整数而已,只不过是类型不同。转化之后,char*指针每加一就会移动一个字节,所以我们能逐个字节的读取到基本类型的数据。
string toBytes( double x ) {
std::size_t size = sizeof(x);
string _return(size,0);
char * start = reinterpret_cast<char *>(&x);
for(std::size_t i = 0; i<size; i++ ) {
_return[i] = *(start + i);
}
return _return;
}
3. 指针强制转化
利用不通指针类型去批量读取字节个数。比如char*每次取值只取一个字节,而long*每次取8个字节。所以我们只要将目标类型的指针指向一片正确的内存区域,我们在利用该指针取值时就能得到正确的数据了。
double getDouble( const string & x ) {
char * p = const_cast<char*>(x.c_str());
double * _return = 0;
_return = reinterpret_cast<double*>(p);
return *_return;
}