Write file from mem to hard disk.

Started by
6 comments, last by VanillaSnake21 15 years, 3 months ago
If I have a struct: struct Foo { int DataSize; char* Data; }; and the Data points to an allocated buffer somewhere in memory, how can I write that whole struct foo to file using ofstream? [Please do not mark threads 'solved' -- jpetrie] [Edited by - jpetrie on January 9, 2009 10:44:23 AM]

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Advertisement
It is fairly simple
Foo n;// ... blah to fill your structure{ofstream ofile("file", ios::binary);ofile.write(n.DataSize, sizeof(int));ofile.write(n.Data,n.DataSize);}


get it back using read()
Foo n;ifstream ifile("file", ios::binary);ifile.read(n.DataSize, sizeof(int));n.Data = new char[n.DataSize];ifile.read(n.Data,n.DataSize);


Perfect thanks, I thought about doing that but for some reason thought that "new" allocations weren't guaranteed to be contiguous.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Not only does the language guarantee that the memory allocated by new[] is contiguous - it would have been impossible *not* to guarantee it. Consider: the return value from new[] is simply a pointer. If the memory were not contiguous, how could you possibly find out where the "other" chunks are so as to use them? :)

In any event, don't make a struct like that; just use std::vector<char>. You can serialize it the same way: write the size (which you can obtain from a vector with the .size() member function), then the data within the allocation (you can get a pointer to the vector's underlying allocation by taking the address of the first element, e.g. '&vec.front()'; the vector's underlying allocation is also guaranteed to be contiguous).
Quote:Original post by Zahlman
Not only does the language guarantee that the memory allocated by new[] is contiguous - it would have been impossible *not* to guarantee it. Consider: the return value from new[] is simply a pointer. If the memory were not contiguous, how could you possibly find out where the "other" chunks are so as to use them? :)

And how can an object know which function to call based on it's type at runtime? Over the years I've been programming in C++, I learned one thing: trust nothing!

Quote:
In any event, don't make a struct like that; just use std::vector<char>. You can serialize it the same way: write the size (which you can obtain from a vector with the .size() member function), then the data within the allocation (you can get a pointer to the vector's underlying allocation by taking the address of the first element, e.g. '&vec.front()'; the vector's underlying allocation is also guaranteed to be contiguous).


Interesting, so how would I allocate this vector? A little sample would be appreciated.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

1) depends on what you are doing. Chances are you can defer this to compile time with better design.

2)
std::vector::size_type sz = 0;
std::vector<char> data;
std::ofstream ofile("file", ios::binary);
ifile.read(&sz, sizeof(sz));
data.resize(sz)
ifile.read(&data.front(),sz);

and you can do this to just read the whole file into a buffer:
std::copy(istream_iterator<char>(ifile), istream_iterator<char>(), back_inserter(data));
Quote:Original post by VanillaSnake21
Quote:
In any event, don't make a struct like that; just use std::vector<char>. You can serialize it the same way: write the size (which you can obtain from a vector with the .size() member function), then the data within the allocation (you can get a pointer to the vector's underlying allocation by taking the address of the first element, e.g. '&vec.front()'; the vector's underlying allocation is also guaranteed to be contiguous).


Interesting, so how would I allocate this vector? A little sample would be appreciated.


You wouldn't "allocate" the vector; you would just declare one, the same way you'd declare an int. I was talking about the vector's allocation - i.e. the memory that is allocated by the code that implements the vector - which is already written for you and provided by the standard library. All you care about is retrieving a pointer to that allocation, so that you can use the file I/O routines with it. (There are more sophisticated techniques using the standard library, too, but they're probably not worth the bother here.)

But yes, pointers can only point at one chunk. Whereas runtime polymorphism can be implemented in a few different ways. :)
@KulSeran thanks for the sample

@Zahlman

I see, so pretty much what Kelsaran did.

Thanks everyone, the vector looks much cleaner then a char*. I'll bet it will also help prevent those nasty memory leaks since I don't have to allocate anything.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

This topic is closed to new replies.

Advertisement