如何在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 但我不知道如何使用它将两个锯齿状阵列保存在一个文件中 并加载它。 )
答案 0 :(得分: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(); }
}
答案 1 :(得分:1)
我找到了两种加载和保存锯齿状阵列的方法。
1)使用BinaryFormatter,如上面提到的Simon Chan所述。 这是一个例子:
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将二维数组转换为一维数组的原因。
我确信有很多方法可以做到这一点。但到目前为止我知道这两种方式。
答案 2 :(得分: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"));