user478571
user478571

Reputation:

reading bytes from binary file to long int

I have two question :

Upvotes: 4

Views: 6238

Answers (3)

You could be concerned by portability of the code and the data: if you exchange binary files between various machines, the binary data will be read as garbage (e.g. because of endianness and word sizes differences). If you only read binary data on the same machine that has written it, it is ok.

Another concern, especially when the data is huge and/or costly, is robustness with respect to evolution of your code base. For instance, if you read a binary structure, and if you had to change the type of one of its fields from int (or int32_t) to long (or int64_t) your binary data file is useless (unless you code specific conversion routines). If the binary file was costly to produce (e.g. needs an experimental device, or a costly computation, to create it) you can be in trouble.

This is why structured textual formats (which are not a silver bullet, but are helpful) or data base management systems are used. Structured textual formats include XML (which is quite complex), Json (which is very simple), and Yaml (complexity & power between those of XML and Json). And textual formats are easier to debug (you could look at them in an editor). There exist several free libraries to deal with these data formats. Data bases are often more or less relational and Sql based. There are several free DBMS software (e.g. PostGresQL or MySQL).

Regards portability of binary files (between various machines) you could be interested by serialization techniques, formats (XDR, Asn1) and libraries (like e.g. S11n and others).

If space or bandwidth is a concern, you might also consider compressing your textual data.

Upvotes: 0

Fred Foo
Fred Foo

Reputation: 363567

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?

Don't assume long is wide enough, it often isn't. long long is guaranteed to be at least 8 bytes wide, though:

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

Mind you, this is still incredibly non-portable due to varying integer sizes and endiannesses.

As for your second question, try

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

std::string str(buf);

or, safer

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

Upvotes: 3

Morten Kristensen
Morten Kristensen

Reputation: 7613

I'm sure you mean 8 bytes into a 64-bit integer instead and there's a variety of ways to accomplish this. One way is to use a 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.
}    

Now rand_num.n will have the integer stored so you can access it.

As for the second question. Read in the bytes and assign them to the string:

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;

Upvotes: 1

Related Questions