保存并加载锯齿状数组
本文关键字:数组 锯齿状 加载 保存 | 更新日期: 2023-09-27 18:20:07
如何在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但我不知道如何使用它将两个锯齿状数组保存在一个文件中并加载它。)
您可以用一些不同的方式使用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) 使用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,我们应该只有一维数组;这就是为什么我使用块拷贝来将二维数组转换为一维数组。
我相信有很多方法可以做到这一点。但到目前为止,我知道这两种方式。
只要使用内置的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"));