开发者

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

开发者 https://www.devze.com 2023-04-04 04:11 出处:网络
Okay, so I\'ve got a game map creater programmed in Java which writes the map out to file using ObjectOutputStream.writeInt()

Okay, so I've got a game map creater programmed in Java which writes the map out to file using ObjectOutputStream.writeInt()

Now I'm converting the game engine to C# XNA and I'm trying to load the map. 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).

Here is the code I'm using to read the height and width of the map in C#.

Edit: br is BinaryReader.

width = (int)IPAddress.Netwo开发者_如何学PythonrkToHostOrder(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#?

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


Absolutely correct:

Java writes as int 32 Big Endian I believe (I could be wrong though).

Remember, though: a .Net Int32 is Little-Endian ;)

[Edit] SOLUTION:

1) Here is Java code that writes 10 integers (Java int's are 32-bit, 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. You'll notice the "using System.Net", in order to get .Net's equivalent of "ntohl()":



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.

public void loadFile(int level)
    {
        ...

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

        ...

    }
0

精彩评论

暂无评论...
验证码 换一张
取 消