So with your method above?
I only read/write primitives.
This model can work between C++ and Java?
Edit: Now that I can see how I can impliment each objects toByte. How should I go about writing the byte array to the file?
Okay I figured out how to write to file I believe using FileChannel.
[Edited by - Halsafar on December 1, 2005 9:50:23 PM]
[java] Write/Read Binary Data of/to a class
Yes, a FileChannel is even better than ByteArray IO streams because you'll be able to work directly with ByteBuffers, changing that interface to something like:
Hope to have helped,
Son Of Cain
public interface BinaryPersistent { /** * Writes the class members into a ByteBuffer instance * and orders the buffer for proper endianness */ ByteBuffer toBytes(); /** * Reads the class members from the given ByteBuffer instance * Requires an ordering of endianness before attempting to read */ void read(ByteBuffer data);}
Hope to have helped,
Son Of Cain
Huge help yes. Rating++.
That is how I had to change the interface to get it to write.
Now, can I read in from file using FileChannel as well right?
If so, I'm sure I can figure it out.
That is how I had to change the interface to get it to write.
Now, can I read in from file using FileChannel as well right?
If so, I'm sure I can figure it out.
Quote:Original post by Halsafar
Now, can I read in from file using FileChannel as well right?
If so, I'm sure I can figure it out.
Yes, you can. And you'll get a ByteBuffer from it.
I suggest you read a bit of the docs for the API, because depending on the size of your files, you'll want to benefit from some features like MappedByteBuffers. This link has several code tips for NIO.
Son Of Cain
Okay I believe you've left me with enough information to accomplish the task.
Particularly that site you gave in your last post.
However, all the examples I'm looking at, including the read/write to bytebuffer via FileChannel examples all allocate the ByteBuffer to be 1024 bytes, enough for 256x4 byte variables. Is there a reason for this? Or could I very well allocate however much space I know I'll need (powers of 2)?
Particularly that site you gave in your last post.
However, all the examples I'm looking at, including the read/write to bytebuffer via FileChannel examples all allocate the ByteBuffer to be 1024 bytes, enough for 256x4 byte variables. Is there a reason for this? Or could I very well allocate however much space I know I'll need (powers of 2)?
Okay I've almost got it.
Except the bytes are coming out proper.
I'll post the code, the expected output, the real output:
Nice to note, the code is a bit messy, cuz I'm messin around with trying to get this to work.
Expected output:
50
50
50
50
50
50
50
0
0
0
0
... (0's for the rest of the btyes)
Actual Output:
50
50
3276800
3276800
50
50
0
0
0
0
.... (the rest is 0's)
Edit: Okay, I shoulda looked over it more. The bytebuffer was only being allocated to 10. So I'm sure I was just overlapping the bytes or something...
[Edited by - Halsafar on December 2, 2005 3:03:34 PM]
Except the bytes are coming out proper.
I'll post the code, the expected output, the real output:
Nice to note, the code is a bit messy, cuz I'm messin around with trying to get this to work.
import java.nio.*;import java.nio.channels.*;import java.io.*;public class test{ public interface BinaryPersistent { abstract public ByteBuffer toBytes(); abstract void read(ByteBuffer data); } private static class A implements BinaryPersistent { int i = 10; public A() { System.out.println("Hello from A"); } public ByteBuffer toBytes() { //Fill some info ByteBuffer buf = ByteBuffer.allocate(1024); buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.putInt(50); // use setters to write data buf.rewind(); // order buffer System.out.println("Converted A to Bytes"); return buf; } public void read(ByteBuffer buffer) { // get data using getXXX() methods on the buffer; } } private static final class B extends A { int j = 20; public B() { System.out.println("Hello from B"); } } public static void main(String[] Args) { B b1 = new B(); File file = new File("filename"); ByteBuffer bbuf = b1.toBytes(); boolean append = false; try { // Create a writable file channel FileChannel wChannel = new FileOutputStream(file, append).getChannel(); // Write the ByteBuffer contents; the bytes between the ByteBuffer's // position and the limit is written to the file wChannel.write(bbuf); // Close the file wChannel.close(); } catch (IOException e) { } try { // Obtain a channel ReadableByteChannel channel = new FileInputStream("filename").getChannel(); // Create a direct ByteBuffer; see also e158 Creating a ByteBuffer ByteBuffer buf = ByteBuffer.allocateDirect(10); int numRead = 0; while (numRead >= 0) { // read() places read bytes at the buffer's position so the // position should always be properly set before calling read() // This method sets the position to 0 buf.rewind(); // Read bytes from the channel numRead = channel.read(buf); // The read() method also moves the position so in order to // read the new bytes, the buffer's position must be set back to 0 buf.rewind(); // Read bytes from ByteBuffer; see also // e159 Getting Bytes from a ByteBuffer for (int i=0; i < numRead / 4; i++) { System.out.println(buf.getInt()); //byte b = buf.get(); } } } catch (Exception e) { } }}
Expected output:
50
50
50
50
50
50
50
0
0
0
0
... (0's for the rest of the btyes)
Actual Output:
50
50
3276800
3276800
50
50
0
0
0
0
.... (the rest is 0's)
Edit: Okay, I shoulda looked over it more. The bytebuffer was only being allocated to 10. So I'm sure I was just overlapping the bytes or something...
[Edited by - Halsafar on December 2, 2005 3:03:34 PM]
Yeah dude, just that ;)
Remember to order the buffer using the correct endianness! Otherwise, you won't be able to use it on the C++ side.
Son Of Cain
Remember to order the buffer using the correct endianness! Otherwise, you won't be able to use it on the C++ side.
Son Of Cain
Yes, that was my next step of business.
Okay so I able to write an int with java and read it with C++. That works fine.
Now my problem is, Java cannot read it back.
I am telling the ByteBuffer in the read part of my snippet to use BIG_ENDIAN. However, thats not working. I believe the ReadableByteChannel gets the bits as they are (LITTLE_ENDIAN) and then it doesn't matter what order the byte buffer is in...
I am always getting the hex opposite of 50, so obviously its coming out of the file in the wrong order.
0x00000032
vs
0x32000000
As soon as I allocate the bytebuffer I call the order() method.
Maybe you can point something out?
I figure a solution would be to try and read the bytes in backwards somehow...
Okay so I able to write an int with java and read it with C++. That works fine.
Now my problem is, Java cannot read it back.
I am telling the ByteBuffer in the read part of my snippet to use BIG_ENDIAN. However, thats not working. I believe the ReadableByteChannel gets the bits as they are (LITTLE_ENDIAN) and then it doesn't matter what order the byte buffer is in...
I am always getting the hex opposite of 50, so obviously its coming out of the file in the wrong order.
0x00000032
vs
0x32000000
As soon as I allocate the bytebuffer I call the order() method.
Maybe you can point something out?
I figure a solution would be to try and read the bytes in backwards somehow...
Quote:Original post by Halsafar
As soon as I allocate the bytebuffer I call the order() method.
Maybe you can point something out?
Are you ordering the ByteBuffer instance AFTER you read data into it? That's how it must be done. If that is not working, then I have no idea what it might be... weird.
If all else fails... is there a way to change the endianness of a binary file in C++? (I'm sure there must be something)
Son Of Cain
Actually. LoL
I just figured it out.
See for Java to read/write a binary which C++ can read/write:
- write as little endian
- read as little endian
I was telling java to write as LITTLE read it as BIG. I have to tell Java to read/write as LITTLE, since the file is in LITTLE.
All fixed. All working.
Thanks a ton for your help.
I just figured it out.
See for Java to read/write a binary which C++ can read/write:
- write as little endian
- read as little endian
I was telling java to write as LITTLE read it as BIG. I have to tell Java to read/write as LITTLE, since the file is in LITTLE.
All fixed. All working.
Thanks a ton for your help.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement