Save and load a jagged array

余生颓废 提交于 2020-01-07 05:05:30

问题


How can I save a jagged array in C#?

For example:

I have the following jagged array:

double[][,] myJaggedArr=new double[2][,];
myJaggedArr[0]=new double[3,3]{{1,2,3},{4,5,6},{7,8,9}};
myJaggedArr[1]=new double[3,3]{{1,1,1},{2,2,2},{3,3,3}};

How can I save this jagged array and how can I load it?

what if I have a two jagged array and I want to save it in one file?

I think it is better to make a class having these two jagged arrays so I can save an object of the class.

I know that I can save using serializer, but I can not use it for jagged array. Do you know how can work around this?

(This is an example of using serializer http://code.google.com/p/protobuf-net/wiki/GettingStarted But I do not know how to use it to save two jagged array in one file and load it. )


回答1:


you can use XML Serialization with little different way. see the example.

 [XmlIgnore]
    public double[][] MyJaggedArr { get; set; }
    [XmlIgnore]
    public double[][] MyJaggedArr2 { get; set; }

    [XmlElement("myJaggedArr")]
    public List<double> MyJaggedArrList
    {
        get { return MyJaggedArr.SelectMany(T => T).ToList();; }
        set { MyJaggedArrList = MyJaggedArr.SelectMany(T => T).ToList(); }
    }

    [XmlElement("myJaggedArr2")]
    public List<double> MyJaggedArr2List
    {
        get { return MyJaggedArr2.SelectMany(T => T).ToList();; }
        set { MyJaggedArrList = MyJaggedArr2.SelectMany(T => T).ToList(); }
    }



回答2:


I found two ways to load and save the jagged array.

1) using BinaryFormatter as Simon Chan suggested above. Here is an example:

 using system.IO;
    using System.Runtime.Serialization.Formatters.Binary;


    [System.Serializable]
    class CudaNetwork {
        public CudaResult[] results {get;set;}
    }
    [System.Serializable]
    class CudaResult {
        public double[] threshold {get;set;}
        public double[,] weight { get; set; }

    }
    var myjaggedArr = new double[2][] { new double[3] { 1, 2, 3 }, new double[3] { 6, 7, 8 } };
    var myjaggedArr2 = new double[2][,] { new double[2,3] { {10,10,10}, {20, 30,50} }, new double[2,3] { {60, 70, 80},{40,30,60} } };


    var myclass = new CudaNetwork
                {
            results = new CudaResult[2] 
           };

                myclass.results[0] = new CudaResult() { threshold = myjaggedArr[0],weight=myjaggedArr2[0] };
                myclass.results[1] = new CudaResult() { threshold = myjaggedArr[1],weight=myjaggedArr2[1] };

var formatter = new BinaryFormatter();

using (
var file = File.Create("mydata.bin"))
{

    formatter.Serialize(file, myclass);
}
using (
var file = File.OpenRead("mydata.bin"))
{
    var obj = formatter.Deserialize(file);
}

2) There is another way to do this using ProtoBuf. Here is an example: (You should add the reference for ProtoBuf at first.)

using ProtoBuf;  
using system.IO;

    [ProtoContract]
    class CudaNetwork {
        [ProtoMember(1)]
        public CudaResult[] results {get;set;}
    }

    [ProtoContract]
    class CudaResult {
        [ProtoMember(1)]
        public double[] threshold {get;set;}
        [ProtoMember(2)]
        public double[] weight { get; set; }

    }



var myjaggedArr = new double[2][] { new double[3] { 1, 2, 3 }, new double[3] { 6, 7, 8 } };
var myjaggedArr2 = new double[2][,] { new double[2,3] { {10,10,10}, {20, 30,50} }, new double[2,3] { {60, 70, 80},{40,30,60} } };

 double[] tmp=new double[myjaggedArr2[0].Length];
 Buffer.BlockCopy(myjaggedArr2[0],0,tmp,0,sizeof(double)*tmp.Length);

 double[] tmp2=new double[myjaggedArr2[1].Length];
 Buffer.BlockCopy(myjaggedArr2[1],0,tmp2,0,sizeof(double)*tmp2.Length);



myclass.results[0] = new CudaResult() { threshold = myjaggedArr[0],weight=tmp };
            myclass.results[1] = new CudaResult() { threshold =myjaggedArr[1] ,weight=tmp2 };

using (var file = File.Create("trainedNetwork.bin")) {
        Serializer.Serialize(file, myclass);
    }


    CudaNetwork cudaclass;
    using (var file =File.OpenRead("trainedNetwork.bin"))
    {

        cudaclass = Serializer.Deserialize<CudaNetwork>(file);
    }

Using ProtoBuf, we should have only one-dimentional array; that is why I used Blockcopy in order to convert the two-dimentional array to one dimentional array.

I am sure there are many ways to do this. But I know these two ways so far.




回答3:


I have no problem serialize a jagged array, just using the built-in BinaryFormatter.

Code example:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

double[][,] myJaggedArr = new double[2][,];
myJaggedArr[0] = new double[3, 3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
myJaggedArr[1] = new double[3, 3] { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } };

var formatter = new BinaryFormatter();
var stream = new MemoryStream();
formatter.Serialize(stream, myJaggedArr);

stream.Position = 0; // Reset the stream position.
var obj = formatter.Deserialize(stream); // Test deserialization.

Then the obj will just contains your jagged array, or you can save stream to a file and load later, using this following code:

formatter.Serialize(File.OpenWrite(@"\file\path\to\save"), myJaggedArr);

And load it using:

// BinaryFormatter.Deserialize() returns an object, you need to cast it to the correct type.
double[][,] obj2 = (double[][,])new BinaryFormatter().Deserialize(File.OpenRead(@"test.bin")); 


来源:https://stackoverflow.com/questions/25598238/save-and-load-a-jagged-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!