问题
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