2014-09-01 129 views
0

如何在C#中保存锯齿阵列?保存并加载锯齿阵列

例如:

我有以下交错数组:

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

我如何保存这种交错的数组,我怎么可以加载呢?

如果我有一个两个参差不齐的数组,我想将它保存在一个文件中?

我认为最好让这两个参差不齐的数组组成一个类,这样我就可以保存这个类的一个对象。

我知道我可以使用序列化器保存,但我不能用它来锯齿状阵列。 你知道如何解决这个问题吗?

(这是使用串行 http://code.google.com/p/protobuf-net/wiki/GettingStarted 的一个例子,但我不知道怎么用它来保存2锯齿形阵列中的一个文件 并加载它。 )

+0

如果您有2个或更多的数组,只需将它们包装在某个类或另一个集合中并将其序列化即可。 – Carsten 2014-09-01 04:28:02

回答

0

我发现了两种方法来加载和保存ja gged数组。

1)使用BinaryFormatter作为西蒙陈建议上面。 下面是一个例子:

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)还有另一种方法来做到这一点使用protobuf的。这里有一个例子: (你应该为protobuf的先加参考。)

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

使用protobuf的,我们应该只有一个 - 维数组;这就是为什么我使用Blockcopy来将二维数组转换为一维数组。

我相信有很多方法可以做到这一点。但到目前为止,我知道这两种方式。

1

您可以使用XML序列化与小不同的方式。看到这个例子。

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

谢谢你的回答。请给我更具体的例子来说明如何使用XmlElement保存和加载数据。我需要任何引用来使用XmlElement吗?那么我应该添加什么来使用它呢?到目前为止,我找到了两种方法来保存锯齿状数组。我会写他们作为可能的答案,但我不知道如何使用XmlElement来保存和加载锯齿状数组。 – Saeed 2014-09-01 19:43:29

0

我没有任何问题序列化锯齿阵列,只是使用内置的BinaryFormatter

代码示例:

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. 

然后obj将只包含您的锯齿状排列,也可以保存stream到一个文件,加载后,使用此下面的代码:

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

和负载它使用:

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

谢谢你的回答。您能否告诉我如何加载文件并将其重新填充为锯齿状数组。我用stream.CopyTo(File.OpenWrite(@“test.bin”));保存到名为test.bin的文件中;它以0KB保存。我认为它不能很好地保存。另外我也知道如何加载这些数据并将其填充到另一个锯齿状数组(或对象)中。 – Saeed 2014-09-01 19:08:15

+0

@Saeed在保存文件之前是否包含'stream.Position = 0;'?或者流从其结尾保存。与示例代码类似,您可以使用'double [] [,] array =(double [] [,])new BinaryFormatter()。Deserialize(File.OpenRead(@“test.bin”));'阵列回来。 – 2014-09-01 20:07:38

+0

谢谢西蒙。它工作正常。唯一的问题是,如果我们对它进行serilize并试图像这样去除它,它会给我们“进程无法访问该文件,因为它正在被另一个进程使用”。我认为这可以通过使用var file = File.OpenRead(“test.bin”)来解决) { var obj = formatter.Deserialize(file); } 谢谢你的帮助。 – Saeed 2014-09-01 20:29:15