【问题标题】:How to write numbers to a file and make them readable between Java and C#如何将数字写入文件并使其在 Java 和 C# 之间可读
【发布时间】:2014-04-28 22:01:18
【问题描述】:

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

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

比如我想依次写3个数字,用下面的schema表示:

  • 第一个数字作为一个“字节”(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,对吗?)。如何处理?

【问题讨论】:

    标签: c# java interop inputstream outputstream


    【解决方案1】:

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

    例如您可以使用 Gson in JavaJson.NET in C# 读取/写入 JSON。该类在 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]
    

    【讨论】:

      【解决方案2】:

      这只是一个字节序问题。您可以使用我的MiscUtil library 从 .NET 读取大端数据。

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

      或者,考虑只使用文本。

      【讨论】:

      • 好的,谢谢,我会尝试,但我将无法使用您的个人库 MiscUtil。有什么“标准”吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 2017-10-18
      相关资源
      最近更新 更多