I'm moving some old C code that generates a binary file into our C# system. The problem is, the resulting binary file will s开发者_JAVA百科till need to be read by another old C program.
The original code outputs several structs to a binary file, and many of those structs contain linked lists, with *next pointers.
How can I write these in C# so that the original program will still be able to read them?
The old C code reads and writes the file a whole struct at a time, with freads and fwrites i.e.
fread ( &file, sizeof ( struct file_items ), 1, hdata.fp );
I can't find a whole lot of info on how fwrite would output the pointers, etc.
If the old code was writing pointers to a file, then odds are you dealing with very poorly written code. Those pointers would be meaningless to any other process reading that file...
Also, reading whole structures with a single fread() is a bad idea because different compilers may pad those structures differently (so the structure written by one application may be laid out differently than one read by another application).
If your code is depending on reading and writing pointer values to a file then it's broken. Every time you run the program it could potentially have a slightly different memory layout.
Instead of writing pointers you should probably convert the pointers into file offsets on write and convert the file offsets back to pointers on read.
(This is true for C, C++ and C#)
The pointers will be meaningless after reading them back, in C or any other language. I assume the pointer-structures are rebuild after reading. This means you can just treat them as fillers while reading/writing.
In .NET, streams only accept byte
and byte[]
as data types, so you will have to convert your structs to/from that format.
One way is to write custom code reading/writing the fields in order. Gives you the most control but it is a lot of work.
The other approach is to map your struct to a byte[] wholesale, I'll look for an example.
The only way you can be (correctly) writing pointers to disk is if you are using something like based addressing:
A linked list that consists of pointers based on a pointer can be saved to disk, then reloaded to another place in memory, with the pointers remaining valid.
Handling this in C# would be extremely difficult and require some kind of mapping layer during serialization.
A pointer refers to a memory location, when you store a pointer in a file, it is meaningless, it refers to something that is ephemeral. So either it does not matter in this application because the data referenced is discared, or you have not stated the format correctly. Normally in such a case you would apply 'serialization', so that the data pointed to were also stored, in the file in such a way that the original data and what it pointed to could be reconstructed ('deserialized') at a later time.
There is no fundamental difference between file storage in C and C# - that is independent of the language, however there may be differences in structure packing, so just storing the structure was always a bad idea (structure packing can vary even between C compilers). Also of course you need to realise that a char
type in C# is 16-bit, not 8. You need to let the existing storage format be the specification and then implement it in C# using serialisation to avoid problems with the differences in structure implementation.
精彩评论