reading bytes from binary file to long int
我有两个问题:
-
我有二进制文件上的数据。 我想使用读取功能读取前8个字节以对long int进行签名,但我不能这样做。 你知道我该怎么做吗?
-
如何直接将一个数据块读取为字符串?
我可以像这样阅读吗
例如:1
2
3
4
5ifstream is;
is.open ("test.txt", ios::binary );
string str ;
is. read ( str.c_str, 40 ) ; // 40 bytes should be read
I want read first 8 bytes to signed long int by using read function but I could not . Do you know how can I do that?
不要假设
1 2 | long long x; is.read(static_cast<char *>(&x), 8); |
请注意,由于整数大小和字节序的变化,这仍然是不可移植的。
至于第二个问题,请尝试
1 2 3 4 5 6 | char buf[41]; is.read(buf, 40); // check for errors buf[40] = '\\0'; std::string str(buf); |
或者,更安全
1 2 3 | char buf[41]; is.get(buf, sizeof(buf), '\\0'); std::string str(buf); |
您可能会担心代码和数据的可移植性:如果在各种机器之间交换二进制文件,则二进制数据将被当作垃圾读取(例如,由于字节序和字长的差异)。如果仅在已写入二进制数据的同一台计算机上读取二进制数据,则可以。
另一个问题,尤其是在数据量巨大和/或成本高昂的情况下,是代码库的健壮性。例如,如果您读取二进制结构,并且必须将其某个字段的类型从
这就是为什么使用结构化的文本格式(不是灵丹妙药,但很有用)或数据库管理系统的原因。结构化的文本格式包括XML(非常复杂),Json(非常简单)和Yaml(XML和Json之间的复杂性和功能)。而且文本格式更易于调试(您可以在编辑器中查看它们)。有几个免费的库可以处理这些数据格式。数据库通常或多或少是基于关系和基于Sql的。有几种免费的DBMS软件(例如PostGresQL或MySQL)。
关于二进制文件(在不同机器之间)的可移植性,您可能会对
序列化技术,格式(XDR,Asn1)和库(例如S11n等)。
如果需要考虑空间或带宽,则还可以考虑压缩文本数据。
我敢肯定,您的意思是将8个字节改为64位整数,并且有多种方法可以实现此目的。一种方法是使用
1 2 3 4 5 6 7 8 9 10 11 | 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. } |
现在
至于第二个问题。读入字节并将它们分配给字符串:
1 2 3 4 5 6 7 | 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; |