簡體   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