从二进制文件读取字节到long int

时间:2011-11-05 11:19:51

标签: c++

我有两个问题:

  • 我有二进制文件的数据。我想通过使用read函数读取前8个字节来签名long int但我不能。你知道我怎么做的吗?

  • 如何直接读取数据块到字符串? 我可以像上面那样阅读 例如:

     ifstream is;
     is.open ("test.txt", ios::binary );
    
     string str ;
     is. read ( str.c_str, 40 ) ; // 40 bytes should be read
    

3 个答案:

答案 0 :(得分:3)

  

我想通过使用read函数读取前8个字节来签名long int但我不能。你知道我怎么能这样做吗?

不要认为long足够宽,通常不是。但long long保证至少为8字节宽:

long long x;
is.read(static_cast<char *>(&x), 8);

请注意,由于整数大小和字节序的变化,这仍然非常难以移植。

至于你的第二个问题,试试

char buf[41];
is.read(buf, 40);
// check for errors
buf[40] = '\0';

std::string str(buf);

或更安全

char buf[41];
is.get(buf, sizeof(buf), '\0');
std::string str(buf);

答案 1 :(得分:0)

我确定你的意思是将8个字节转换为64位整数,而且有多种方法可以实现这一目标。一种方法是使用union

union char_long {
  char chars[8];
  uint64_t n;
};

// Extract 8 bytes and combine into a 64-bit number by using the
// internals of the union structure.
char_long rand_num;  
for(int i = 0; i < 8; i++) {
  rand_num.chars[i] = in.get(); // `in` is the istream.
}    

现在rand_num.n将存储整数,以便您可以访问它。

至于第二个问题。读入字节并将它们分配给字符串:

const int len = 5; // Some amount.
char *buf = new char[len];
ifstream in("/path/to/file", ios::binary);
in.read(buf, len);
string str;
str.assign(buf);
delete[] buf;

答案 2 :(得分:0)

您可能会担心代码和数据的可移植性:如果您在各种计算机之间交换二进制文件,二进制数据将被视为垃圾(例如,由于字节顺序和字大小差异)。如果您只在已编写二进制数据的同一台机器上读取二进制数据,则可以。

另一个问题,特别是当数据庞大和/或成本高昂时,就代码库的演变而言是健壮的。例如,如果您阅读二进制结构,并且必须将其中一个字段的类型从int(或int32_t)更改为long(或int64_t )您的二进制数据文件是无用的(除非您编写特定的转换例程)。如果生成二进制文件成本很高(例如需要实验设备,或者需要昂贵的计算,那么创建它)可能会遇到麻烦。

这就是使用结构化文本格式(不是灵丹妙药,但有用)或数据库管理系统的原因。结构化文本格式包括XML(非常复杂),Json(非常简单)和Yaml(XML和Json之间的复杂性和功能)。文本格式更容易调试(您可以在编辑器中查看它们)。有几个免费的库来处理这些数据格式。数据库通常或多或少是关系型的,基于Sql。有几个免费的DBMS软件(例如PostGresQLMySQL)。

考虑您可能感兴趣的二进制文件(在各种机器之间)的可移植性 serialization种技术,格式(XDRAsn1)和图书馆(例如S11n等)。

如果需要考虑空间或带宽,您可能还会考虑compressing您的文字数据。