如何将数字写入文件并使其在Java和c#之间可读

本文关键字:Java 之间 数字 文件 | 更新日期: 2023-09-27 17:51:16

我遇到了同一个程序的两个版本之间的"兼容性"问题,第一个是用Java编写的,第二个是c#的移植。

我的目标是将一些数据写入文件(例如,在Java中),例如数字序列,然后能够在c#中读取它。显然,操作应该以相反的顺序进行。

例如,我想按顺序写3个数字,用以下模式表示:

  • 第一个数字为一个'字节'(4位)
  • 第二个数字作为一个'整数'(32位)
  • 第三个数字为一个'整数'(32位)

因此,我可以在一个新文件上放置以下序列:2(作为字节),120(作为int32), 180(作为int32)

在Java中,编写过程大致是这样的:

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();

阅读部分如下:

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#代码如下所示。写作:

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);
阅读:

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);

请注意,当程序的相同Java/c#版本写入和读取文件时,这两个过程都有效。问题是当我试图从c#版本读取Java程序编写的文件时,反之亦然。读取的整数总是"奇怪"的数字(如-1451020…)。

与c#相比,Java存储和读取32位整数值(总是signed,对吧?)的方式肯定存在兼容性问题。如何处理这种情况?

如何将数字写入文件并使其在Java和c#之间可读

这只是一个端序问题。你可以使用我的MiscUtil库从。net读取大端数据。

但是,我强烈建议对Java和。net使用更简单的方法:

  • Java中使用DataInputStreamDataOutputStream。没有必要让ByteBuffer等变得复杂。
  • 在。net中,使用来自MiscUtil的EndianBinaryReader,它扩展了BinaryReader(同样EndianBinaryWriter也扩展了BinaryWriter)

我会考虑使用XML或JSON等标准格式来存储数据。然后,您可以使用Java和c#中的标准序列化器来读写文件。这种方法使您可以轻松地命名数据字段,从多种语言中读取它,如果有人在文本编辑器中打开文件,则易于理解,并且更容易添加要序列化的数据。

。你可以在Java和JSON中使用Gson读写JSON。. NET中的c#。这个类在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);

它会序列化为

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

Java也同样非常简单。您可以在每个库中找到如何读/写文件的示例。

或者如果数组是一个更好的数据模型:

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