By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,418 Members | 1,094 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,418 IT Pros & Developers. It's quick & easy.

Writing raw data on disk.

P: 78
Hi guys.

I am messing around with virtual file systems lately, but i have a problem.
I want to save a structure on the virtual disk as raw data. How can i do this? Should i convert each "member" inside the struct to char?
like: "encrypt" and "decript" thingy?
Note: I'm writing char[] buffer to the disk!

Thanks!
Jun 6 '07 #1
Share this Question
Share on Google+
13 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
Yes, the file stream is a char file stream. You may also want field delimiters to you can read the data back in.

Expand|Select|Wrap|Line Numbers
  1. struct Date
  2.         {
  3.             int month;
  4.             int day;
  5.             int year;
  6.         };
  7.         Date dt;
  8.         dt.month = 7;
  9.         dt.day = 4;
  10.         dt.year = 1776;
  11.         fstream output("c:\\scratch\\instructor\\testdata.txt", ios::out);
  12.         stringstream  ss;
  13.         ss << dt.month << '|' << dt.day << '|' << dt.year << '\n';
  14.         string buffer;
  15.         ss >> buffer;
  16.         output.write(buffer.c_str(), buffer.size());
  17.  
Jun 6 '07 #2

Savage
Expert 100+
P: 1,764
Yes, the file stream is a char file stream. You may also want field delimiters to you can read the data back in.

Expand|Select|Wrap|Line Numbers
  1. struct Date
  2.         {
  3.             int month;
  4.             int day;
  5.             int year;
  6.         };
  7.         Date dt;
  8.         dt.month = 7;
  9.         dt.day = 4;
  10.         dt.year = 1776;
  11.         fstream output("c:\\scratch\\instructor\\testdata.txt", ios::out);
  12.         stringstream  ss;
  13.         ss << dt.month << '|' << dt.day << '|' << dt.year << '\n';
  14.         string buffer;
  15.         ss >> buffer;
  16.         output.write(buffer.c_str(), buffer.size());
  17.  
If he will be using >> to extract data,I think that whitespace can serve as a delimiter.
Jun 6 '07 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
If he will be using >> to extract data,I think that whitespace can serve as a delimiter.
That's an if.

And it's another if that the data does not contain whitespace.

However, depending upon the answers to those two if's, then you may be correct.
Jun 6 '07 #4

P: 78
I'm really sorry, but i forgot to mention a key factor. I'm working in C.

P.S. The problem i want to avoid is, if the data structure is 512 bytes, i want to write 512 bytes to disk. Converting short types to characters will occupy more space!
Jun 7 '07 #5

P: 78
Ok, i've been thinking really hard (it hurts too). I can solve this if i find a method to convert a 2 byte short int to a 2 byte char.
Any chance i can read a byte from the short?
Thanks!
Jun 7 '07 #6

Savage
Expert 100+
P: 1,764
I'm really sorry, but i forgot to mention a key factor. I'm working in C.

P.S. The problem i want to avoid is, if the data structure is 512 bytes, i want to write 512 bytes to disk. Converting short types to characters will occupy more space!
use itoa.It converts numbers to string with using bases,like 10 for decimal and so on.

Savage
Jun 7 '07 #7

AdrianH
Expert 100+
P: 1,251
Ok, i've been thinking really hard (it hurts too). I can solve this if i find a method to convert a 2 byte short int to a 2 byte char.
Any chance i can read a byte from the short?
Thanks!
What you just asked is impossible. A char is one byte long and a short is two.

You want to write binary data to a file? That's easy. Cast the struct instance's address to a void*.

Actually, in C you don't even need to cast since it uses a weak type system you can assign any pointer type to void * and void * to any pointer type. Since fread and fwrite take a void * for the buffer, you just plop the address of the struct and use sizeof(youStruct) as the size.

BUT BE WARNED, this file you create will not be portable across different CPU platforms. If you don't care, go right ahead.


Adrian
Jun 7 '07 #8

P: 78
Well my implementation writes and reads blocks of data, so i use char* buffers to read and write. Making itvoid* wouldn't work would it?

But, i've found a way to do it. I've created two functions, struct_to_string and string_to_struct. The first converts the structure to a char*. The structure only contains characters and shorts, so the problem is with shorts. What i did is store the first 8 bits of short in 1 char and the last 8 bits inthe other.Then the string_to_struct reforms the structure, and in case of shorts, it recreates them using binary operations.

It cost me precious time (because i have a deadline...) butit works like charm!

Thanks for the help anyway guys!:)
Jun 7 '07 #9

Savage
Expert 100+
P: 1,764
Well my implementation writes and reads blocks of data, so i use char* buffers to read and write. Making itvoid* wouldn't work would it?

But, i've found a way to do it. I've created two functions, struct_to_string and string_to_struct. The first converts the structure to a char*. The structure only contains characters and shorts, so the problem is with shorts. What i did is store the first 8 bits of short in 1 char and the last 8 bits inthe other.Then the string_to_struct reforms the structure, and in case of shorts, it recreates them using binary operations.

It cost me precious time (because i have a deadline...) butit works like charm!

Thanks for the help anyway guys!:)
Intresting,we are glad that u have solved it.

Savage
Jun 7 '07 #10

AdrianH
Expert 100+
P: 1,251
Well my implementation writes and reads blocks of data, so i use char* buffers to read and write. Making itvoid* wouldn't work would it?

But, i've found a way to do it. I've created two functions, struct_to_string and string_to_struct. The first converts the structure to a char*. The structure only contains characters and shorts, so the problem is with shorts. What i did is store the first 8 bits of short in 1 char and the last 8 bits inthe other.Then the string_to_struct reforms the structure, and in case of shorts, it recreates them using binary operations.

It cost me precious time (because i have a deadline...) butit works like charm!

Thanks for the help anyway guys!:)
Expand|Select|Wrap|Line Numbers
  1. struct A
  2. {
  3.   char aString[6];
  4.   short aShort;
  5. };
  6.  
  7. struct A a = { "Hello", 4 };
  8. fwrite(&a, sizeof(struct A), 1, outfile);
  9.  
  10. struct A a;
  11. fread(&a, sizeof(struct A), 1, infile);
I didn't include opening the respective files. I'll leave that to you.

Basicly, what you did is the same thing, with one major difference. Yours is done so that you can change the implementation of how it reads and write it in the appropriate functions. With mine your stuck esp if you are reading/writing in several locations, unless you wrap these up in appropriate functions that take a FILE* parameter.

Yours is more flexable, which is definatly good as you can potentially make it endian compatiable across CPUs.


Adrian
Jun 7 '07 #11

P: 78
Hmm, interesting. I didn't know you could write a void* using fwrite.
Glad you showed me :)
Jun 8 '07 #12

AdrianH
Expert 100+
P: 1,251
Hmm, interesting. I didn't know you could write a void* using fwrite.
I'm not writing a void*, I'm writing a struct A instance.
Glad you showed me :)
No problem.


Adrian
Jun 8 '07 #13

AdrianH
Expert 100+
P: 1,251
Actually, in C you don't even need to cast since it uses a weak type system you can assign any pointer type to void * and void * to any pointer type. Since fread and fwrite take a void * for the buffer, you just plop the address of the struct and use sizeof(youStruct) as the size.
In C++ this goes only one way, almost anything to a void *. When going from a void * to anything, you require a reinterpret cast.


Adrian
Jun 8 '07 #14

Post your reply

Sign in to post your reply or Sign up for a free account.