简体   繁体   中英

DeSerializing a byte stream into an Java Class

I have nested "C" language data structures like this:

struct xyz {
  char a[256];
  char b[1024];
} XYZ;

struct abc {
  unsigned char dat1[1024];
  int dat2;
} ABC;

struct def {
  int x;
  int y;
  int z;
} DEF;

struct tot {
  XYZ p1;
  ABC p2[45];
  DEF p3[17];
} TOT;

TOT tot;

After populating TOT, i write it to a file like this in the C program.

fwrite((char *)&tot,1,sizeof(TOT),file);

Now I have to read that same file back using a JAVA program, and re-create the same C data structures as corresponding JAVA classes for ANDROID.

So I make classes that look like the C structures above, those classes just contain the data members and no methods like this

class XYZ {
  byte a[]=new byte[256];
  byte b[]=new byte[1024];
} XYZ;

class ABC {
  byte dat1[1024];
  int dat2;
};

class DEF {
  int x;
  int y;
  int z;
};

class TOT {
  XYZ p1;
  ABC p2[45];
  DEF p3[17];
};

I know there is some syntax error in the classes above but i hope you get the idea.

So how can I read all the bytes from the file and use that to create all these nested JAVA class objects as you see above to match the original C structures at the top?

I guess its like a de-serialization in JAVA (Android), but the serializer was a C program using fwrite.

It would be so hard to read the bytes one by one from the file, and fill in the JAVA class objects manually, and also while taking account for the different sizes of the data types and byte orders from Windows C to JAVA, is there a faster way?

Unfortunately the binary data is already written to the file using C and cant be changed, so I have to write a JAVA program to get it back and make those class objects from it.

thanks very much for any ideas!

You can do this fairly easily with a DataInputStream , provided the sender is using network byte order.

If it isn't, I can only suggest that you throw the C end away and start again with a properly defined application protocol. As I keep saying here, 'don't use structs as application protocols. Use application protocols as application protocols'. You could look at XDR for example.

The easiest way to load those structures into memory is the use of ByteBuffer , since you can control the endian order.

The following example will load the entire file into memory first, before build the Java objects. Since the Java objects will take even more memory than that, it shouldn't be a major problem.

The fields of the classes have been corrected too.

The code assumes little-endian order (x86 processor) and that the C int was 4 bytes, ie mapping to a Java int .

ByteBuffer buffer = ByteBuffer.wrap(Files.readAllBytes(Paths.get("C:/fileFromC.bin")));
buffer.order(ByteOrder.LITTLE_ENDIAN); // if C code was run on x86 processor
TOT tot = TOT.load(buffer);
class XYZ {
    byte a[] = new byte[256];
    byte b[] = new byte[1024];
    static XYZ load(ByteBuffer buffer) {
        XYZ xyz = new XYZ();
        buffer.get(xyz.a);
        buffer.get(xyz.b);
        return xyz;
    }
}
class ABC {
    byte[] dat1 = new byte[1024];
    int dat2;
    static ABC load(ByteBuffer buffer) {
        ABC abc = new ABC();
        buffer.get(abc.dat1);
        abc.dat2 = buffer.getInt();
        return abc;
    }
}
class DEF {
    int x;
    int y;
    int z;
    static DEF load(ByteBuffer buffer) {
        DEF def = new DEF();
        def.x = buffer.getInt();
        def.y = buffer.getInt();
        def.z = buffer.getInt();
        return def;
    }
}
class TOT {
    XYZ p1;
    ABC[] p2 = new ABC[45];
    DEF[] p3 = new DEF[17];
    static TOT load(ByteBuffer buffer) {
        TOT tot = new TOT();
        tot.p1 = XYZ.load(buffer);
        for (int i = 0; i < tot.p2.length; i++)
            tot.p2[i] = ABC.load(buffer);
        for (int i = 0; i < tot.p3.length; i++)
            tot.p3[i] = DEF.load(buffer);
        return tot;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM