将3d int数组写入文件(并更新)的最佳方法是什么?

时间:2014-06-19 09:38:55

标签: c# arrays multidimensional-array writetofile

我试图以可以轻松检索和更新的格式将3d数组保存到文件中。我找不到一个简单的方法,我没有太多运气。

它是一个3维的int数组。我更喜欢类似这样的保存方法:

//save
for (int z1 = 0; z1 <= z; z1++)
{
  for (int c = 0; c < m.Length; c++)
  {
    for (int x = 0; x < 4; x++)
    {
      writeToFile("matrix.txt", matrix[z1][c][x];
    }
  }
}

和类似的检索方法,但此时我一点都不挑剔,任何可以保存到文件并且易于检索的东西都可以。

以上只是首选,因为它允许我只保存包含数据的数组部分。

数组的大小类似于m [4000] [7000] [4],但它的人口稀少。

编辑:经过长时间运行后,我的机器无法运行这个大小的数组,所以我将转而使用xml数据集。谢谢大家的建议,对不起,我无法更好地实施它们。

4 个答案:

答案 0 :(得分:2)

你需要什么 - 是工具。

现在这些是我的建议还有其他解决方案,甚至更适合......

首先去here并熟悉这个库。你需要的可能是this sparse matrix data structure或者Sparse vector

其次,如果你不关心保存文件的格式,那么.Net有一个很棒的东西叫做二进制序列化explained here

现在这一切听起来都很复杂,但它几乎与以下几行有关:     //这是在没有VS的情况下写的......

// create a matrix, Im using a dense one, but you can use a sparse matrix in pretty much the same way
Matrix<double> matrix = DenseMatrix.OfArray(new double[,] {
        {1,1,1,1},
        {1,2,3,4},
        {4,3,2,1}});

var formatter = new BinaryFormatter();

// saving
using(var fileStream1 = File.Create("file.file"))
{
    formatter.Serialize(fileStream1, matrix);
}

Matrix<double> newMatrix= null;

// retreving    
using(var fileStream2 = File.Open("file.file"))
{
    newMatrix = (Matrix<double>)formatter.DeSerialize(fileStream2);
}

性能方面,这应该对稀疏矩阵非常有效(示例显示密集矩阵),因为Math.Net使用CSR所以保存它们的数据......

链接: http://numerics.mathdotnet.com/docs/ http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra.Single/SparseMatrix.htm http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra.Single/SparseVector.htm http://msdn.microsoft.com/en-us/library/72hyey7b%28v=vs.110%29.aspx http://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR_or_CRS.29

答案 1 :(得分:1)

你可以使用类似于图论的东西,你可以将图形保存为adiacent节点列表,但在你的情况下扩展到3维:只保存值不同于0的数据。 另一方面,您应该使用int [,,] matrix=new int[4000,7000,4]形式的多个数组,而不是单独的索引。 考虑到之前的结果,您的保存方法可能如下所示:

for (int z1 = 0; z1 <= z; z1++)
{
    for (int c = 0; c < m.Length; c++)
    {
        for (int x = 0; x < 4; x++)
        {
            if(matrix[z1,c,x]!=0)
            {
                File.AppendAllText("matrix.txt",z1+" "+c+" "+x+" "+matrix[z1,c,x]+System.Environment.NewLine)//NewLine to isolate each matrix value on a different line
            }
        }
    }
}

同样,您的Read方法应如下所示:

string[] lines=File.ReadAllLines("matrix.txt");
//assuming your matrix is initialized with 0s
foreach(string line in lines)
{
    string[] elementsInLine=line.Split(' ');
    int z1=int.Parse(elementsInLine[0]);
    int c=int.Parse(elementsInLine[1]);
    int x=int.Parse(elementsInLine[2]);
    matrix[z1,c,x]=int.Parse(elementsInLine[3]);
}

我已经对输出/输入文件的格式做了一些假设,希望它们对您有所帮助。

答案 2 :(得分:1)

您可以使用Newtonsoft.Json库序列化您的集合,然后将其写入文件。

http://james.newtonking.com/json

您可以使用StreamWriter / StreamReader对文件进行i / o操作

示例:http://james.newtonking.com/json/help/index.html?topic=html/SerializingJSON.htm

答案 3 :(得分:1)

鉴于你的数组只是稀疏填充,只写出非零值似乎是最好的方法。

    const int DIM0 = 4000;
    const int DIM1 = 7000;
    const int DIM2 = 4;
    int[, ,] array = new int[DIM0 , DIM1 , DIM2 ];

    void writeArray(string fileName)
    {
        StringBuilder SB = new StringBuilder();

        for (int k=0; k < DIM2 ; k++)
        for (int j=0; j < DIM1 ; j++)
        for (int i=0; i < DIM0 ; i++)
        {
            if (array[i,j,k] != 0)
                SB.Append(String.Format("{0},{1},{2},{3}\r\n",i,j,k,array[i,j,k]) );
        }
        File.WriteAllText(fileName, SB.ToString().TrimEnd('\r').TrimEnd('\n')  );
    }

    void readArray(string fileName)
    {
        string s = File.ReadAllText(fileName).Replace("\r","");
        string[] p = s.Split('\n');
        bool error = false;
        foreach (string e in p)
        {
            string[] n = e.Split(',');
            int i = 0; int j = 0; int k = 0; int v = 0;
            error  = !Int32.TryParse(n[0], out i) ;
            error &= !Int32.TryParse(n[1], out j);
            error &= !Int32.TryParse(n[2], out k);
            error &= !Int32.TryParse(n[3], out v);
            if (!error) array[i, j, k] = v;
            else { /*abort with error message..*/}
        }
    }

编辑:我已经交换了&#39 ;;&#39;对于换行符,以防万一数组填充不那么薄,所以没有线路长度限制可以被击中..