Reputation: 61
Quick noob question which is really bothering me, I am serializing a DataTable array however when deserializing it back an exception is thrown for 'The input stream is not a valid binary format'
Serialization
public static bool saveToFile(DataTable[] NW, string path)
{
try
{
using (var stream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream,NW);
stream.Close();
File.WriteAllBytes(path,stream.ToArray());
}
return true;
}
catch(Exception ex)
{
MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
return false;
}
}
Deserialization
public static DataTable[] loadFromFile(string path)
{
try
{
byte[] buffer = File.ReadAllBytes(path);
var stream = new MemoryStream(buffer);
IFormatter formatter = new BinaryFormatter();
return (DataTable[])formatter.Deserialize(stream);
}
catch(Exception ex)
{
MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
return null;
}
}
I've also tried it without the MemoryStream and used instead the File Stream returned by File.Open(string path, FileMode.Create/Open)
Also, just before writing it to the file this is the look of the byte array:
When reading it
It looks like as it didn't really wrote everything to the file?
Upvotes: 1
Views: 6696
Reputation: 2154
public static class DataTableSerializer
{
public static byte[] FastSerialize(this DataTable tbl, out string tableSchema)
{
var tableItems = new object[tbl.Rows.Count][];
for (var rowIndex = 0; rowIndex < tbl.Rows.Count; rowIndex++)
tableItems[rowIndex] = tbl.Rows[rowIndex].ItemArray;
var serializationFormatter = new BinaryFormatter();
using (var buffer = new MemoryStream())
{
serializationFormatter.Serialize(buffer, tableItems);
var tableSchemaBuilder = new StringBuilder();
tbl.WriteXmlSchema(new StringWriter(tableSchemaBuilder));
tableSchema = tableSchemaBuilder.ToString();
return buffer.ToArray();
}
}
public static DataTable FastDeserialize(byte[] serializedData, string tableSchema)
{
var table = new DataTable();
table.ReadXmlSchema(new StringReader(tableSchema));
var serializationFormatter = new BinaryFormatter();
object[][] itemArrayForRows;
using (var buffer = new MemoryStream(serializedData))
{
itemArrayForRows = (object[][]) serializationFormatter.Deserialize(buffer);
}
table.MinimumCapacity = itemArrayForRows.Length;
table.BeginLoadData();
for (var index = 0; index < itemArrayForRows.Length; index++)
{
var t = itemArrayForRows[index];
table.Rows.Add(t);
}
table.EndLoadData();
return table;
}
}
Upvotes: 2
Reputation: 61
Following Lu Henry comment, It is actually working by moving the tables to a dataset and then write it.
public static bool saveToFile(DataTable[] NW, string path)
{
try
{
var NWDS = new DataSet();
foreach (DataTable dt in NW) {
NWDS.Tables.Add(dt.Copy());
}
NWDS.WriteXml(File.Create(path));
return true;
}
catch(Exception ex)
{
MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
return false;
}
}
public static DataTable[] loadFromFile(string path)
{
try
{
var NWDS = new DataSet();
NWDS.ReadXml(File.Open(path,FileMode.Open));
var NW = new DataTable[15];
NWDS.Tables.CopyTo(NW,0);
return NW;
}
catch(Exception ex)
{
MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
return null;
}
}
Upvotes: 1