如何从C#中的二进制文件读取2D int数组?

时间:2018-11-03 21:20:07

标签: c# arrays file

我有一个二维整数数组来存储x,y坐标。我检查了一些将2D数组写入文件的功能,但是找不到任何能够在加载时读取该二进制文件并将其推入新的二维整数数组的东西。

这是我的世界生成器函数,将其保存到文件中:

stream = File.Open(@"C:\x86\Debug\xml.xml", FileMode.OpenOrCreate);

有什么好主意可以读取此文件?我应该找回2D整数数组,public WorldGenerator() { int worldSizeX = 100; int worldSizeY = 100; int[,] world = new int[worldSizeX*worldSizeY, 2]; Logger.log("Generating world..."); for(int x = 0; x < worldSizeX; x++) { for(int y = 0; y < 2; y++) { System.Random random = new System.Random(); int itemID = random.Next(0, 1); world[x, y] = itemID; } } FileStream fs = new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/ConsoleGame/world/default.wd", FileMode.OpenOrCreate, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fs); for (int x = 0; x < worldSizeX; x++) { for (int y = 0; y < 2; y++) { bw.Write(world[x, y]); } } bw.Close(); fs.Close(); Logger.log("World generated."); } 应该拿给我itemid。我是C#的新手,这只是一个基本的控制台应用程序。 我还看到其他人回答了类似的问题,但对我来说还没有一个工作。可能是因为此保存功能有误或其他原因。

编辑:

这是我加载文件的方式:

world[0,0]

2 个答案:

答案 0 :(得分:0)

需要Newtonsoft.Json

enter image description here

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace ConsoleApp18
{
    class Program
    {
        static void Main(string[] args)
        {
            int worldSizeX = 100;
            int worldSizeY = 100;

            int[,] world = new int[worldSizeX * worldSizeY, 2];

            System.Random random = new System.Random();

            for (int x = 0; x < worldSizeX; x++)
            {
                for (int y = 0; y < 2; y++)
                {

                    int itemID = random.Next(0, 2);
                    world[x, y] = itemID;
                }
            }


            string json = JsonConvert.SerializeObject(world, Formatting.Indented);
            System.IO.File.WriteAllText("WriteText.txt", json);

            string text = System.IO.File.ReadAllText("WriteText.txt");
            int[,] deserialized = JsonConvert.DeserializeObject<int[,]>(text);

            //use "deserialized"

        }



    }

}

答案 1 :(得分:0)

您需要的被称为“序列化”。 从简单的内置binary serializer开始。

Serializable属性在这里发挥了魔力。

等到您意识到这不是最佳选择时,您就可以使用更适合自己需求的内容,例如proto-buf

在您的示例中,我还将ints更改为shorts。我怀疑每个世界单元是否需要32位,因此我们可以节省一些硬盘空间。

[Serializable]
public class WorldState
{
    public short[,] Items { get; set; }

    public void Save(string filename)
    {
        if (filename == null) throw new ArgumentNullException(nameof(filename));

        using (var file = File.Create(filename))
        {
            var serializer = new BinaryFormatter();
            serializer.Serialize(file, this);
        }
    }

    public static WorldState Load(string filename)
    {
        if (filename == null) throw new ArgumentNullException(nameof(filename));
        if (!File.Exists(filename)) throw new FileNotFoundException("File not found", filename);

        using (var file = File.OpenRead(filename))
        {
            var serializer = new BinaryFormatter();
            return serializer.Deserialize(file) as WorldState;
        }
    }
}

public class WorldStateTests
{
    [Fact]
    public void CanSaveAndLoad()
    {
        var ws = new WorldState
        {
            Items = new short[,]
            {
                { 1, 2, 3, 4 },
                { 1, 2, 3, 4 },
                { 1, 2, 3, 4 },
                { 1, 2, 3, 4 }
            }
        };
        // save the world state to file. Find it and see what's inside 
        ws.Save("./ws.bin");

        // load the world back
        var loaded = WorldState.Load("./ws.bin");

        // check a new world state got loaded
        Assert.NotNull(loaded);
        // and it still has items
        Assert.NotEmpty(loaded.Items);
        // and the items are the same as we saved
        Assert.Equal(ws.Items, loaded.Items);
    }
}