• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1414
  • Last Modified:

How to read binary files in Java and typecast to a object type?

Experts,

I created a binary file using C file apis and written a structure say
struct A
{  char a;
    int b;
    long c;
};

And Now a Java application is reading this file,
So, in java we created the same object type similar to above structure and reading to the object from file.
I am getting an execption here.
Is this not possible?

To check this we tried creating a binary file writing the same data which we updated in C to compare both the binary files (in c and in java)
to identify any difference in file data.
And we observed that both the files are not identical.
Please comment.
0
srimallikarthik
Asked:
srimallikarthik
  • 4
  • 3
  • 3
2 Solutions
 
objectsCommented:
need to see how you are reading it
0
 
srimallikarthikAuthor Commented:
Here is my java code which is reading from the binary file :

package javaapplication9;

/**
 *
 * @author karthik.kp
 */
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Main {
  public static void main(String[] args) throws Exception {
    Junk obj1 = new Junk(1,'2',3);
 int counter = 0;


/* ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
    new FileOutputStream("C:\\Users\\karthik.kp\\Documents\\Visual Studio 2008\\Projects\\structtest\\structtest\\javabin.bin")));
for ( counter=1; counter <= 2; counter++)
            {
                  objectOut.writeObject(obj1);
                       
            }

objectOut.close();
  */

    //ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(
       // new FileOutputStream("C:/JunkObjects.bin")));
    //objectOut.writeObject(obj1); // Write object
   // objectOut.close(); // Close the output stream

    ObjectInputStream objectIn = null;
   
    Junk object = null;

    objectIn = new ObjectInputStream(new BufferedInputStream(new FileInputStream(
        "C:\\Users\\karthik.kp\\Documents\\Visual Studio 2008\\Projects\\structtest\\structtest\\ex3.bin")));

    // Read from the stream until we hit the end
    //while (objectCount < 3) {
    //  object = (Junk) objectIn.readObject();
    //  objectCount++;
    //  System.out.println(object);
    //}
   
for ( counter=1; counter <= 2; counter++)
            {
                  object = (Junk) objectIn.readObject();
                        System.out.println(object);
            }
    objectIn.close();

  }
}

class Junk implements Serializable {
  int x;
  char y;
  long z;

  public Junk(int x,char y, long z) {
    this.x=x;
    this.y=y;
    this.z=z;
  }

}
0
 
objectsCommented:
you can't use ObjectInputStream, it is only for object written with ObjectOutputStream
You'll need to read it 'manually', reading the data as it has been written by your C app
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
wdosanjosCommented:
A couple things that come to mind:

1. Java uses 2 bytes for a char, in C is just 1 byte

2. Java uses Big Endian for integers, in C depends on the machine (on x86/x64 is Little Endian)
0
 
srimallikarthikAuthor Commented:
Is it possible to read the bin file data mannually like in C app and typecast it to the type of C struct which i am writing to file.

I understand that data types differ in c and java from the above post.

Will there is any way to do this labourous job easy way ? (i.e.  interpreting the read C type struct data from binary file to java object data types)
0
 
objectsCommented:
No short cuts really, the following may give you some insight
http://stackoverflow.com/questions/277944/best-way-to-read-structured-binary-files-with-java

you're better off writing to something like xml and reading that from java
0
 
wdosanjosCommented:
If you have control over the C code, it's probably easier to change it to write the data in the Java binary format.
0
 
srimallikarthikAuthor Commented:
Yes , i do have control over the C code layer,

Can you please add little more info to make me understand how i can change it easily to java  binary format? ( one example would be of great help)
0
 
objectsCommented:
easier to use an interchange format such as xml
0
 
wdosanjosCommented:
Assuming you are running the C code on a Little Endian machine, the int and long values must be converted to Big Endian before writing then to the file.  The link below has the code for the conversion functions, which I reproduce below.

http://www.codeguru.com/forum/showthread.php?t=292902
inline void endian_swap(unsigned short& x)  // 16-bit 'short'
{
    x = (x>>8) | 
        (x<<8);
}

inline void endian_swap(unsigned int& x)  // 32-bit 'int'
{
    x = (x>>24) | 
        ((x<<8) & 0x00FF0000) |
        ((x>>8) & 0x0000FF00) |
        (x<<24);
}

// __int64 for MSVC, "long long" for gcc
inline void endian_swap(unsigned __int64& x)  // 64-bit (possibly 'long')
{
    x = (x>>56) | 
        ((x<<40) & 0x00FF000000000000) |
        ((x<<24) & 0x0000FF0000000000) |
        ((x<<8)  & 0x000000FF00000000) |
        ((x>>8)  & 0x00000000FF000000) |
        ((x>>24) & 0x0000000000FF0000) |
        ((x>>40) & 0x000000000000FF00) |
        (x<<56);
}

Open in new window


Then on the Java side, you should read the variables one at a time in the same sequence they were written in C.  Something like this:

import java.io.*;

public class Main
{
    public static void main(String[] args) throws Exception
    {
        new Main().Run();
    }

    private void Run() throws Exception
    {
        ObjectInputStream in = new ObjectInputStream(
                        new BufferedInputStream(
                        new FileInputStream("C:\\Users\\karthik.kp\\Documents\\Visual Studio 2008\\Projects\\structtest\\structtest\\ex3.bin")));

        try
        {
            for(;;)
            {
                Junk obj = new Junk();

                obj.x = in.readInt(); // 32-bit 'int'
                obj.y = (char)in.readByte();
                obj.z = in.readLong(); // 64-bit 'long'

                System.out.println(obj);
            }
        }
        catch(EOFException ex)
        {
        }
        finally
        {
            in.close();
        }
    }

    public class Junk implements Serializable
    {
        public int x;
        public char y;
        public long z;

        public String ToString()
        {
            return "" + x + "," + y + "," + x;
        }
    }
}

Open in new window


I hope this helps.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now