How to write numbers to a file and make them readable between Java and C#

I'm into a "compatibility" issue between two versions of the same program, the first one written in Java, the second it's a port in C#.

My goal is to write some data to a file (for example, in Java), like a sequence of numbers, then to have the ability to read it in C#. Obviously, the operation should work in the reversed order.

For example, I want to write 3 numbers in sequence, represented with the following schema:

  • first number as one 'byte' (4 bit)
  • second number as one 'integer' (32 bit)
  • third number as one 'integer' (32 bit)

So, I can put on a new file the following sequence: 2 (as byte), 120 (as int32), 180 (as int32)

In Java, the writing procedure is more or less this one:

FileOutputStream outputStream;
byte[] byteToWrite;
// ... initialization....

// first byte
outputStream.write(first_byte);

// integers
byteToWrite = ByteBuffer.allocate(4).putInt(first_integer).array();
outputStream.write(byteToWrite);
byteToWrite = ByteBuffer.allocate(4).putInt(second_integer).array();
outputStream.write(byteToWrite);

outputStream.close();

While the reading part it's the following:

FileInputStream inputStream;
ByteBuffer byteToRead;
// ... initialization....

// first byte
first_byte = inputStream.read();

// integers
byteToRead = ByteBuffer.allocate(4);
inputStream.read(byteToRead.array());
first_integer = byteToRead.getInt();

byteToRead = ByteBuffer.allocate(4);
inputStream.read(byteToRead.array());
second_integer = byteToRead.getInt();

inputStream.close();

C# code is the following. Writing:

FileStream fs;
byte[] byteToWrite;
// ... initialization....

// first byte
byteToWrite = new byte[1];
byteToWrite[0] = first_byte;
fs.Write(byteToWrite, 0, byteToWrite.Length);

// integers
byteToWrite = BitConverter.GetBytes(first_integer);
fs.Write(byteToWrite, 0, byteToWrite.Length);
byteToWrite = BitConverter.GetBytes(second_integer);
fs.Write(byteToWrite, 0, byteToWrite.Length);

Reading:

FileStream fs;
byte[] byteToWrite;
// ... initialization....

// first byte
byte[] firstByteBuff = new byte[1];
fs.Read(firstByteBuff, 0, firstByteBuff.Length);
first_byte = firstByteBuff[0];

// integers
byteToRead = new byte[4 * 2];
fs.Read(byteToRead, 0, byteToRead.Length);
first_integer = BitConverter.ToInt32(byteToRead, 0);
second_integer = BitConverter.ToInt32(byteToRead, 4);

Please note that both the procedures works when the same Java/C# version of the program writes and reads the file. The problem is when I try to read a file written by the Java program from the C# version and viceversa. Readed integers are always "strange" numbers (like -1451020...).

There's surely a compatibility issue regarding the way Java stores and reads 32bit integer values (always signed, right?), in contrast to C#. How to handle this?

Jon Skeet
people
quotationmark

It's just an endian-ness issue. You can use my MiscUtil library to read big-endian data from .NET.

However, I would strongly advise a simpler approach to both your Java and your .NET:

Alternatively, consider just using text instead.

people

See more on this question at Stackoverflow