4

For example in C I have structure:

typedef struct {
    int number;
    double x1;
    double y1;
    double x2;
    double y2;
    double x3;
    double y3;
} CTRstruct;`

Then I write it to file fwrite(&tr, 1, sizeof(tr), fp); (tr - its CTRstruct var, fp - File pointer);

Then I need to read it with Java! I really don't know how to read struct from file... I tried to read it with ObjectInputStream(), last idea is to read with RandomAccessFile() but I also don't know how to... (readLong(), readDouble() also doesn't work, it works ofcource but doesn't read correct data). So, any idea how to read C struct from binary file with Java?


If it's interesting, my version to read integer (but it's ugly, & I don't know what to do with double):

public class MyDataInputStream extends DataInputStream{

public MyDataInputStream(InputStream AIs) {
    super(AIs);
}

public int readInt1() throws IOException{
    int ch1 = in.read();
    int ch2 = in.read();
    int ch3 = in.read();
    int ch4 = in.read();
    if ((ch1 | ch2 | ch3 | ch4) < 0)
        throw new EOFException();
    return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}

with double we can deal the same way (like with int or with long (8bytes) & then convert to double with native func).

8
  • 1
    The way you write the struct to file is wrong, take a look at this: stackoverflow.com/questions/10153155/… Commented Apr 15, 2012 at 14:32
  • 4
    The actually correct answer would be to not dump the memory representation of the struct to a file like this. Commented Apr 15, 2012 at 14:34
  • yes, mb it's silly to do like this, but i need to do it.. (I mean to write in file the hole struct) Commented Apr 15, 2012 at 14:37
  • 2
    You did open the file as binary? I.e. fp = fopen("some/file", "wb");? Then you have to watch out for things like padding and how Java handle endianess for the integer, and if double is the same format. Commented Apr 15, 2012 at 14:38
  • 2
    @Daunn Well since no answer will be capable of providing the "correct" answer in all cases, the simplest solution would be to just read all zeros. Sure that's almost always wrong - but that's at least better than being wrong only every 100th time. Makes debugging much simpler Commented Apr 15, 2012 at 14:47

6 Answers 6

5

You should not use fwrite of the entire struct, because you will inevitably run into issues with padding and endian-ness. The C side will dump the entire struct the way it is in the memory, with all its gaps that the compiler puts in for performance etc. That's "the mother of non-portability"!

Instead, you should use protocol buffers, JSON, or some other mean of portable serialization to accomplish your task.

Sign up to request clarification or add additional context in comments.

Comments

4

Use a library that serializes your data to disk. That will make reading it back into Java a whole lot easier. Make sure that the library uses a well-documented storage format.

Comments

2

You have to find out what size those C types (int, double) and which endianness (thanks andrew cooke) are used in the architecture you executed the program in and use same sized types in Java.

1 Comment

and what endinanness. java assumes big-endian; for little endian use ledatastream.softupto.com
1

DataInputStream is the typical way to read primitive inputs in Java -- I think you ought to be able to do

int number = dataInputStream.readInt();
double x1 = dataInputStream.readDouble();
...
double y3 = dataInputStream.readDouble();

but I'm not 100% sure that endianness and other issues will be compatible.

4 Comments

I would expect that the padding between the int and the first double needs to be handled.
It's really totally dependent on how C decides to represent it in memory; it'd be best to actually do that one field at a time, properly, rather than just dumping the in-memory representation.
Well the first question is: Is the int 4 or 8 byte? If it's 4 byte we probably have to use padding, if not it fits fine, but suddenly we can't use a java int anymore but need a long. And so on and so on. It's just a really bad idea.
int 4 byte, it seems to me, cause these methods work incorrect
1

Well, in the unlikely event that JNI is an option for you, you could read it back in C. Using swig you could easily expose your struct, along with its function to read from the file. Of course all the hassle that comes with JNI isn't worth for this problem alone, but you might already be using it.

Comments

0

I use http://javolution.org/ (or https://github.com/javolution/javolution) . Even if the project seems 'dead', I didn't find anything as simple and efficient that it for "Struct".

Have a look here to know how to create a Class that map the buffer: Struct Javadoc

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.