简体   繁体   English

写Java ObjectOutputStream.writeInt()用BinaryReader在C#中读取?

[英]Write Java ObjectOutputStream.writeInt() read with BinaryReader in C#?

Okay, so I've got a game map creater programmed in Java which writes the map out to file using ObjectOutputStream.writeInt() 好的,所以我有一个用Java编程的游戏地图创建器,它使用ObjectOutputStream.writeInt()将地图写到文件中。

Now I'm converting the game engine to C# XNA and I'm trying to load the map. 现在,我将游戏引擎转换为C#XNA,并尝试加载地图。 I'm getting numerical errors though, so I'm wondering if anyone knows what I'm doing wrong? 我虽然遇到数字错误,但我想知道是否有人知道我在做什么错?

Java writes as int 32 Big Endian I believe (I could be wrong though). 我相信Java写成int 32 Big Endian(不过我可能错了)。

Here is the code I'm using to read the height and width of the map in C#. 这是我用来读取C#地图高度和宽度的代码。

Edit: br is BinaryReader. 编辑:br是BinaryReader。

width = (int)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(br.ReadBytes(sizeof(int)), 0));
height = (int)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(br.ReadBytes(sizeof(int)), 0));

Can anyone please tell me what I'm doing wrong? 谁能告诉我我做错了什么? Or how to read the bytes from ObjectOutputStream.writeInt() properly in C#? 或者如何在C#中正确地从ObjectOutputStream.writeInt()读取字节?

Edit: 2nd try failed. 编辑:第二次尝试失败。 here is the current code: 这是当前代码:

public byte[] ReadBigEndianBytes(int count, BinaryReader br)
        {
            byte[] bytes = new byte[count];
            for (int i = count - 1; i >= 0; i--)
                bytes[i] = br.ReadByte();

            return bytes;
        }

        public void loadFile(int level)
        {
            FileStream fs = new FileStream("map" + level + ".lv", FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs, System.Text.Encoding.BigEndianUnicode);

            width =  BitConverter.ToInt32(ReadBigEndianBytes(4, br), 0);
            height = BitConverter.ToInt32(ReadBigEndianBytes(4, br), 0);

            tile = new int[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    tile[x, y] = BitConverter.ToInt32(ReadBigEndianBytes(4, br), 0);
                }
            }

        }
    }
ObjectOutputStream.writeInt()

Don't use that. 不要使用它。 Use DataOutputStream.writeInt(). 使用DataOutputStream.writeInt()。 It does the same thing, in network byte order, but it doesn't add the Serialziation header that ObjectOutputStream adds, so you won't have to skip it at the .NET end. 它以网络字节顺序执行相同的操作,但是它没有添加ObjectOutputStream添加的Serialziation头,因此您不必在.NET端跳过它。

Absolutely correct: 完全正确:

Java writes as int 32 Big Endian I believe (I could be wrong though). 我相信Java写成int 32 Big Endian(不过我可能错了)。

Remember, though: a .Net Int32 is Little-Endian ;) 不过请记住:.Net Int32是Little-Endian;)

[Edit] SOLUTION: [编辑]解决方案:

1) Here is Java code that writes 10 integers (Java int's are 32-bit, Big-endian)) 1)这是写10个整数的Java代码(Java int是32位的Big-endian)


    import java.io.*;

    public class WriteBinary {

      public static void main (String[] args) {
        int[] data = {
          1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        };

        String fname = "myfile.bin";
        try
        {
          System.out.println("Opening " + fname + "...");      
          FileOutputStream fos = 
            new FileOutputStream(fname);
          int ibyte;
          for (int i = 0; i < data.length; i++) {
            ibyte = ((data[i] >>> 24) & 0xff); fos.write(ibyte);
            ibyte = ((data[i] >>> 16) & 0xff); fos.write(ibyte);
            ibyte = ((data[i] >>> 8) & 0xff); fos.write(ibyte);
            ibyte = (data[i] & 0xff); fos.write(ibyte);
          }
          fos.close();
          System.out.println("File write complete.");      
        }
        catch (IOException e) {
          System.out.println ("I/O error: " + e.getMessage());
        }
      }
    }

2) Here is the C# code that reads it. 2)这是读取它的C#代码。 You'll notice the "using System.Net", in order to get .Net's equivalent of "ntohl()": 您会注意到“正在使用System.Net”,以便获得等效于“ ntohl()”的.Net:



using System;
using System.IO;
using System.Net;

namespace ReadBinary
{
    class Program
    {
        static void Main(string[] args)
        {
            string fname = "myfile.bin";
            try
            {
                Console.WriteLine("Opening " + fname + "...");
                BinaryReader br =
                  new BinaryReader(
                        File.Open(fname, FileMode.Open));
                for (int i = 0; i < (int)(br.BaseStream.Length / 4); i++)
                {
                    int j =
                        System.Net.IPAddress.NetworkToHostOrder (br.ReadInt32());
                    Console.WriteLine("array[" + i + "]=" + j + "...");
                }
                br.Close();
                Console.WriteLine("Read complete.");
            }
            catch (IOException ex)
            {
                Console.WriteLine("I/O error" + ex.Message);
            }
        }
    }
}

I think a proper way is to use IPAddress.NetworkToHostOrder(Int32) method. 我认为正确的方法是使用IPAddress.NetworkToHostOrder(Int32)方法。

public void loadFile(int level)
    {
        ...

        width =  IPAddress.NetworkToHostOrder(br.ReadInt32());
        height = IPAddress.NetworkToHostOrder(br.ReadInt32());

        ...

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM