www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - reading a structure (eg header info) from file

reply captaindet <2krnk gmx.net> writes:
hi,

whilst converting some of my C code into D i got stuck.

in C:

typedef struct { /* info */ } INFO;
INFO info;
size_t checkio;
// read INFO from data file:
pf_datafile = fopen("datafile","rb");
checkio = fread((char *) &info, sizeof(info), 1, pf_datafile);

how do i do this in D? i'd like to avoid falling back to calling C functions,
but i cannot figure out how do this with phobos functions. mind you, eventually
the INFO struct might be anywhere in the file, not only at the beginning.

cheers,

det  
Jul 03 2013
next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Wednesday, 3 July 2013 at 20:37:24 UTC, captaindet wrote:
 hi,

 whilst converting some of my C code into D i got stuck.

 in C:

 typedef struct { /* info */ } INFO;
 INFO info;
 size_t checkio;
 // read INFO from data file:
 pf_datafile = fopen("datafile","rb");
 checkio = fread((char *) &info, sizeof(info), 1, pf_datafile);

 how do i do this in D? i'd like to avoid falling back to 
 calling C functions, but i cannot figure out how do this with 
 phobos functions. mind you, eventually the INFO struct might be 
 anywhere in the file, not only at the beginning.

 cheers,

 det
you wish to read a whole file as text. When I tested it things like string didn't work but numbers did. Maybe someone else here can help you if you need that.
Jul 03 2013
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/03/2013 01:37 PM, captaindet wrote:

 in C:

 typedef struct { /* info */ } INFO;
 INFO info;
 size_t checkio;
 // read INFO from data file:
 pf_datafile = fopen("datafile","rb");
 checkio = fread((char *) &info, sizeof(info), 1, pf_datafile);
Just a reminder: The operation above is not portable. There are endianness and struct member padding issues.
 how do i do this in D?
Assuming that the writer and the reader agree that it works, the closest in Phobos is std.stdio.rawRead.
 the INFO struct might be anywhere in the file, not only at the beginning.
seek() does that. import std.stdio; struct Info { size_t a; double b; byte c; } void main() { auto info0 = Info(1, 2.25, 3); auto info1 = Info(4, 5.50, 6); writeTest("test_file", [ info0, info1 ]); readTest("test_file", 0); readTest("test_file", 1); } void writeTest(string fileName, const(Info)[] infos) { auto file = File(fileName, "w"); file.rawWrite(infos); } void readTest(string fileName, size_t index) { auto file = File(fileName, "r"); auto offset = index * Info.sizeof; file.seek(offset); // More than 1 would read as many elements auto info = new Info[1]; file.rawRead(info); writefln("Read Info at index %s: %s", index, info); } Ali
Jul 03 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, July 03, 2013 15:37:28 captaindet wrote:
 hi,
 
 whilst converting some of my C code into D i got stuck.
 
 in C:
 
 typedef struct { /* info */ } INFO;
 INFO info;
 size_t checkio;
 // read INFO from data file:
 pf_datafile = fopen("datafile","rb");
 checkio = fread((char *) &info, sizeof(info), 1, pf_datafile);
 
 how do i do this in D? i'd like to avoid falling back to calling C
 functions, but i cannot figure out how do this with phobos functions. mind
 you, eventually the INFO struct might be anywhere in the file, not only at
 the beginning.
You should probably look at std.stdio.File. It looks like its readf function might be what you're looking for. If not, there are quite a few functions on there, and it's likely that you could get one of them to do what you want. Or you could always use std.mmfile.MmFile and operate on the file as an array and do it all that way (memory-mapped I/O is one of the coolest things ever IMHO). - Jonathan M Davis
Jul 03 2013
prev sibling parent reply "captaindet" <2krnk gmx.net> writes:
thanks everyone for your help!

i should have mentioned that i did play with std.stdio.File.readf
and rawRead but was too thick to figure out a working solution.

o i could not figure out how to make readf work with my self
defined struct

o same with rawRead. but here i understand my mistake now: i have
to pass an array of my struct, even if i only want to read it
once.

endianness and padding are certainly issues. i have spent some
time figuring out how to adjust struct packing in D. my
definitions are now full of align(2) declarations... as for the
endianness, as i can oversee it now all potential users will sit
on little-endian machines. the group of users is small, just our
workgroup.

the datafiles in question are produced by some 3rd party 16bit
windows software, so i have to accept the way the data is stored
in the file. also, they can be as big as 2GB so reading in the
whole file is not an option.

thanks again,

det
Jul 04 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
captaindet:

 as for the
 endianness, as i can oversee it now all potential users will sit
 on little-endian machines. the group of users is small, just our
 workgroup.
If you are able to put a tag in your file that specifies the endianess, using Phobos it's not hard to convert the data to the right endianess of the CPU where the D code is running. Bye, bearophile
Jul 04 2013