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

时光怂恿深爱的人放手 提交于 2019-12-25 04:28:24

问题


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?


回答1:


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:

  • In Java, use DataInputStream and DataOutputStream. There's no need to get complicated with ByteBuffer etc.
  • In .NET, use EndianBinaryReader from MiscUtil, which extends BinaryReader (and likewise EndianBinaryWriter for BinaryWriter)

Alternatively, consider just using text instead.




回答2:


I'd consider using a standard format like XML or JSON to store your data. Then you can use standard serializers in both Java and C# to read/write the file. This sort of approach lets you easily name the data fields, read it from many languages, be easily understandable if someone opens the file in a text editor, and more easily add data to be serialized.

E.g. you can read/write JSON with Gson in Java and Json.NET in C#. The class might look like this in C#:

public class MyData
{
    public byte FirstValue { get; set; }
    public int SecondValue { get; set; }
    public int ThirdValue { get; set; }
}

// serialize to string example
var myData = new MyData { FirstValue = 2, SecondValue = 5, ThirdValue = -1 };
string serialized = JsonConvert.SerializeObject(myData);

It would serialize to

{"FirstValue":2,"SecondValue":5,"ThirdValue":-1}

The Java would, similarly, be quite simple. You can find examples of how to read/write files in each library.

Or if an array would be a better model for your data:

string serialized = JsonConvert.SerializeObject(new[] { 2, 5, -1 }); // [2,5,-1]


来源:https://stackoverflow.com/questions/22560406/how-to-write-numbers-to-a-file-and-make-them-readable-between-java-and-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!