繁体   English   中英

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

[英]How to read 2D int array from binary file in c#?

我有一个二维整数数组来存储x,y坐标。 我签出了一些函数来将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.");
}

有什么好主意可以读取此文件? 我应该找回2D整数数组,而world[0,0]应该让我得到itemid。 我是C#的新手,这只是一个基本的控制台应用程序。 我还看到其他人回答了类似的问题,但对我来说还没有一个工作。 可能是因为此保存功能有误或其他原因。

编辑:

这是我加载文件的方式:

using (var filestream = File.Open(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/ConsoleGame/world/default.wd", FileMode.Open))
using (var binaryStream = new BinaryReader(filestream))
{
    while (binaryStream.PeekChar() != -1)
    {
        Console.WriteLine(binaryStream.ReadInt32());
    }
}

需要Newtonsoft.Json

在此处输入图片说明

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"

        }



    }

}

您需要的是“序列化”。 从简单的内置二进制序列化器开始

可序列化属性在这里很神奇。

现在,您将意识到这不是最佳选择,您将能够使用更适合您需求的东西,例如proto-buf

在您的示例中,我也将ints更改为短裤。 我怀疑每个世界单元需要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);
    }
}

暂无
暂无

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

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