Win32 file I/O with structures
This is probably a stupid question but how do I write a structure to a file with the Win32 API?
This is how I do it in DOS:
struct Map_Cell{
unsigned int Tile;
unsigned char Type;
unsigned char Tag;
}Grid[24][16];
FILE *fp;
if((fp=fopen("a:/maps/test.bin","r+b"))!=NULL) {
rewind(fp);
if(fwrite(&Grid, sizeof(struct Map_Cell), 1, fp)<1) {
puts("File write error.");
}
fclose(fp);
}
Any help would be appreciated.
Edited by - The_C_Guy on 6/9/00 2:25:58 AM
http://www.crosswinds.net/~druidgames/resist.jpg
Just because you''re in Windows doesn''t mean you HAVE TO use the Win32 API. I used that old DOS code (not that exact code, but you get my point ) in my MFC map editor and it works fine!
I dont even use the API for file operations so i have no idea what functions there are.
=======================================
A man with no head is still a man.
A head with no man is plain freaky.
I dont even use the API for file operations so i have no idea what functions there are.
=======================================
A man with no head is still a man.
A head with no man is plain freaky.
Zipster, maybe he wants to learn how to do that with the Win32 API? Although *I* think it's better to use the "old C way", since it's more portable than using the Win32 API and probably a lot easier too
/. Muzzafarath
Mad House Software
Edited by - Muzzafarath on June 9, 2000 4:11:46 AM
/. Muzzafarath
Mad House Software
Edited by - Muzzafarath on June 9, 2000 4:11:46 AM
I'm reminded of the day my daughter came in, looked over my shoulder at some Perl 4 code, and said, "What is that, swearing?" - Larry Wall
Whoa! haven't used the Win32 file I/O APIs in a while...let's see if I can remember. OK, it's coming back to me. I'll write an example at the end. It really only differs from the C standard library file I/O (fopen, fread, fwrite, etc.) in naming and a few odd conventions. I read that either the C library functions call the Win32 I/O functions, or the reverse. Regardless, you don't need to learn them if you only want to do simple I/O in Windows. (Plus the file functions in Windows feature something called overlapped I/O, but I've never used it.
To open a file, you use CreateFile(). It has a lot of flags, which basically accomplish the same things as the "rb" etc. string options. Just OR the flags together like bit-flags. The docs give a very thorough explanation of these flags, and there are just too many to list here.
After you have a file open, you use ReadFile() and WriteFile() just like fread and fwrite, except that it doesn't give an option of how many elements to write. Just call it multiple times, or write large chunks. It's all raw data anyway. I do know that the API functions do buffered I/O by default, so they -should- be relatively fast. You can use SetFilePointer() kind of like fseek(), too.
The overlapped I/O seems like overkill for a game or editor, but I haven't really used it. Just start with the normal functions and use them like the C stuff:
Don't worry about the amount of flags for CreateFile() -- the ones I've given can be used in most any situation you encounter, except that you'll replace CREATE_NEW with another flag if you want the file to stay around.
Oh yeah, if you want to write a struct to a file, you just do something like this:
Basically, you write the whole struct as one large chunk of memory. The sizeof() operator that I've been using is C++ and it just gives you the size of any data type (even your own types).
- null_pointer
Sabre Multimedia
Edited by - null_pointer on June 9, 2000 7:52:13 AM
To open a file, you use CreateFile(). It has a lot of flags, which basically accomplish the same things as the "rb" etc. string options. Just OR the flags together like bit-flags. The docs give a very thorough explanation of these flags, and there are just too many to list here.
After you have a file open, you use ReadFile() and WriteFile() just like fread and fwrite, except that it doesn't give an option of how many elements to write. Just call it multiple times, or write large chunks. It's all raw data anyway. I do know that the API functions do buffered I/O by default, so they -should- be relatively fast. You can use SetFilePointer() kind of like fseek(), too.
The overlapped I/O seems like overkill for a game or editor, but I haven't really used it. Just start with the normal functions and use them like the C stuff:
// like fopen()
// create the file if it doesn't exist, and indicate that
// we'll be using it basically like sequential access.
// (the sequential flag is just a hint for caching -- it
// doesn't actually restrict us.)
HANDLE file_handle = CreateFile("testfile.dat", GENERIC_READ / GENERIC_WRITE, FILE_SHARE_READ / FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL / FILE_FLAG_RANDOM_ACCESS);
int x=5, y=7, z=9;
// like fwrite()
// write 12 bytes
WriteFile(file_handle, &x, sizeof(int));
WriteFile(file_handle, &y, sizeof(int));
WriteFile(file_handle, &z, sizeof(int));
// like fseek()
// seek to the beginning
SetFilePointer(file_handle, 0, 0, FILE_BEGIN);
// like fread()
// read 12 bytes
ReadFile(file_handle, &x, sizeof(int));
ReadFile(file_handle, &y, sizeof(int));
ReadFile(file_handle, &z, sizeof(int));
// like fclose()
CloseHandle(file_handle);
// double-check what we've read
if( x != 5 // y != 7 // z != 9 )
MessageBox(NULL, "file I/O test did not work correctly...", "error", MB_OK);
Don't worry about the amount of flags for CreateFile() -- the ones I've given can be used in most any situation you encounter, except that you'll replace CREATE_NEW with another flag if you want the file to stay around.
Oh yeah, if you want to write a struct to a file, you just do something like this:
struct MYDATA
{
int data1;
long data2;
char data3;
short data4;
char data 5;
}; // 12 bytes
void WriteMyDataToFile(MYDATA* pData, HANDLE file_handle)
{
// sizeof(MYDATA) == 12 bytes
WriteFile(file_handle, sizeof(MYDATA), 0, pData);
}
Basically, you write the whole struct as one large chunk of memory. The sizeof() operator that I've been using is C++ and it just gives you the size of any data type (even your own types).
- null_pointer
Sabre Multimedia
Edited by - null_pointer on June 9, 2000 7:52:13 AM
>> I read that either the C library functions call the Win32 I/O functions, or the reverse. <<
It''s probably the reverse, seeing as the Win32 I/O functions doesn''t exist on every platform where there''s a C compiler
/. Muzzafarath
Mad House Software
It''s probably the reverse, seeing as the Win32 I/O functions doesn''t exist on every platform where there''s a C compiler
/. Muzzafarath
Mad House Software
I'm reminded of the day my daughter came in, looked over my shoulder at some Perl 4 code, and said, "What is that, swearing?" - Larry Wall
Just like to point out that it is much easier to read/write data under UNIX. Doesn''t matter if its a string or a structure you just use the read and write commands.
Just thought I would had my 2 cents worth
Just thought I would had my 2 cents worth
-----------------------------------------------All messages are of my own personal opinion and not meant to offend. But if they do - tough :)Neuro.
zipster.. you''re using stdio in an MFC app? thats just.. evil . have you looked into file serialization?
--
Float like a butterfly, bite like a crocodile.
--
Float like a butterfly, bite like a crocodile.
--Float like a butterfly, bite like a crocodile.
quote: Original post by Muzzafarath
>> I read that either the C library functions call the Win32 I/O functions, or the reverse. <<
It''s probably the reverse, seeing as the Win32 I/O functions doesn''t exist on every platform where there''s a C compiler
Actually, it''s the C library functions on Win32 call the Win32 I/O functions. Otherwise how else would the be implemented? It''s not like a new version of the libraries had to be shipped when FAT32 came out. Similarly C file access library functions call UNIX API functions on UNIX boxes, etc.
Also, using the Win32 API is necessary when writing to non-file file descriptors i.e. pipes, mailslots, etc.
Serialization in MFC subclasses from CObject your data storing classes. These classes implement the Serialize() method of CObject so that dynamic members or other raw data is stored in the CArchive class that the CObject is being serialized from/to.
Relevant articles in MSDN: "Serialization: Serializing an Object" and "Serialization: Making a Serializable Class".
orpheum - its a win32/MFC beast. when you save or load files from the File menu in most windows programs, the program is using file serialization. basically, documents have a serialization function that can be overloaded, you pass stuff in and out of a default stream and win32 handles the rest for ya.
--
Float like a butterfly, bite like a crocodile.
--
Float like a butterfly, bite like a crocodile.
--Float like a butterfly, bite like a crocodile.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement