简体   繁体   English

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

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

I have a 2D integer array to store x,y coordinates. 我有一个二维整数数组来存储x,y坐标。 I checked out a few functions to write 2D array into a file but cannot find anything that is able to read that binary file on load and push it into a new 2 dimensional integer array. 我签出了一些函数来将2D数组写入文件,但是找不到能够在加载时读取该二进制文件并将其推入新的二维整数数组的任何内容。

This is my world generator function which saves it to the file: 这是我的世界生成器函数,将其保存到文件中:

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.");
}

Any good idea that could work for reading this file in? 有什么好主意可以读取此文件? I should get back a 2D integer array and world[0,0] should get me the itemid. 我应该找回2D整数数组,而world[0,0]应该让我得到itemid。 I am new to c# and this would be just a basic console application. 我是C#的新手,这只是一个基本的控制台应用程序。 I have also seen others answering similar questions but none of them are worked for me yet. 我还看到其他人回答了类似的问题,但对我来说还没有一个工作。 Maybe because this save function is wrong or something else. 可能是因为此保存功能有误或其他原因。

EDIT: 编辑:

Here is how I load the file: 这是我加载文件的方式:

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());
    }
}

need Newtonsoft.Json 需要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"

        }



    }

}

What you need is called "Serialization". 您需要的是“序列化”。 Start with the simple builtin binary serializer . 从简单的内置二进制序列化器开始

Serializable attribute does the magic here. 可序列化属性在这里很神奇。

By the moment you'll realize it is not the best option, you'll be able to use something more suiting your needs, like proto-buf . 现在,您将意识到这不是最佳选择,您将能够使用更适合您需求的东西,例如proto-buf

I've also changed ints to shorts in your example. 在您的示例中,我也将ints更改为短裤。 I doubt you need 32 bits for each world cell, so we can save a bit of hard drive space. 我怀疑每个世界单元需要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