如何将数字写入文件并使它们在Java和C#之间可读 [英] How to write numbers to a file and make them readable between Java and C#
问题描述
我陷入了同一个程序的两个版本之间的兼容性"问题,第一个版本是用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
,对吗?)的方式方面肯定存在兼容性问题.该如何处理?
这只是一个字节序问题.您可以使用我的 MiscUtil库从.NET读取大端数据.>
但是,我强烈建议您对Java和.NET采取更简单的方法:
- 在Java中,使用
DataInputStream
和DataOutputStream
.无需复杂地使用ByteBuffer
等. - 在.NET中,使用MiscUtil中的
EndianBinaryReader
,该文件扩展了BinaryWriter
)
或者,考虑只使用文本.
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?
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
andDataOutputStream
. There's no need to get complicated withByteBuffer
etc. - In .NET, use
EndianBinaryReader
from MiscUtil, which extendsBinaryReader
(and likewiseEndianBinaryWriter
forBinaryWriter
)
Alternatively, consider just using text instead.
这篇关于如何将数字写入文件并使它们在Java和C#之间可读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!