VB6 Code:
' declarations ' 16 byte data storage Private Type TimeSales5 ntSymNum As Byte ntDay As Byte ntMonth As Byte ntYear As Integer ntHour As Byte ntMinute As Byte ntSecond As Byte ntBid As Long ntAsk As Long End Type
VB6 Code:
' Main Load Routine Sub LoadFromFile(ByVal sName as string) dim uTick() as TimeSales5 iFreeTSFile = FreeFile Open "C:CompleteData2\" & sName & ".ts3" For Binary As #iFreeTSFile cLen = LOF(iFreeTSFile) lRecords = cLen / 16 - 1 If lRecords >= 0 Then ' size the uTick type to receive all the file's records ReDim uTick(lRecords) Get #iFreeTSFile, , uTick ' load all the data ' code to assign the fields from uTick to native ' types (double, long etc) End If End Sub
Simple VB6 code to save all data in a user defined type one line of code based on the snippet above might be:
Put #iFreeTSFile, , uTick
Is there an equivalent to VB6 binary file writing of user defined types in C#? I searched quite a bit for a simple yet elegant solution to reading and writing custom file formats in C#. The answer, it seems is using C#'s Stream object for file access and BinaryFormatter to serialize a custom data class to and from disk.
Now that the table has been set, it's time for a paradigm shift from the VB6 mentality of writing binary files to the C# way of writing data to file via Serialization. There are other ways to write data to file in C# but using C# Serialization and DeSerialization for file writing and reading seems most similar to writing a VB6 user defined type to file in one shot or reading from file in one shot.
Code from SaveFormat class
And finally this is the LoadFile class
Put #iFreeTSFile, , uTick
Is there an equivalent to VB6 binary file writing of user defined types in C#? I searched quite a bit for a simple yet elegant solution to reading and writing custom file formats in C#. The answer, it seems is using C#'s Stream object for file access and BinaryFormatter to serialize a custom data class to and from disk.
Now that the table has been set, it's time for a paradigm shift from the VB6 mentality of writing binary files to the C# way of writing data to file via Serialization. There are other ways to write data to file in C# but using C# Serialization and DeSerialization for file writing and reading seems most similar to writing a VB6 user defined type to file in one shot or reading from file in one shot.
Code from SaveFormat class
C# Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyNamespace { [Serializable()] class SaveFormat { private static int MAXROWS = 1000; private static int MAXTABS = 50; public DateTime[] dateTime = new DateTime[MAXROWS]; public double[, ,] EquityCurve = new double[4, MAXTABS, MAXROWS]; public int[] EquityCurveIndex = new int[MAXROWS]; } }
Note the [Serializable()] attribute which tells C# that the SaveFormat class may be written to and read from a file. The class can contain any data format you need to store and retrieve, including as in the above example, multidimensional arrays.
Code from SaveFile class
Code from SaveFile class
C# Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; namespace MyNamespace { class SaveFile { public static void SaveMultiA(SaveFormat Data, string name) { try { using (Stream stream = File.Open (name , FileMode.Create)) { BinaryFormatter bin = new BinaryFormatter(); bin.Serialize(stream, Data); } } catch (IOException ex) { MessageBox.Show("Error Saving SaveFormat Storage Class : " + ex.ToString()); } } } }
The SaveFile class essentially just creates a new C# Stream object with the specified file name and the FileMode.Create option. This stream object is then plugged into a new BinaryFormatter object using the Serialize method. The entire SaveFormat class (and this could be any format) is then serialized to disk via BinaryFormatter.
C# Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; namespace MyNamespace { class LoadFile { public static void LoadMultiA(ref SaveFormat Data, string name) { try { if (!File.Exists(name)) return; using (Stream stream = File.Open (name , FileMode.Open)) { BinaryFormatter bin = new BinaryFormatter(); Data = (SaveFormat)bin.Deserialize(stream); } } catch (IOException ex) { MessageBox.Show("Error Loading SaveFormat Storage Class : " + ex.ToString()); } } } }
The LoadFile class just does this in reverse. Again a new Stream object is created with a valid file name, using the FileMode.Open option. The stream object is then plugged in again to the BinaryFormatter object using the Deserialize method. the Data is cast as (SaveFormat) to ensure the proper translation of the bits.
Allow me to pause for a moment to admire the beauty of the C# code I just posted. While this may seem like a lot of code, sans the using statements, this is just a few lines of actual code in C# and it gives me that good feeling I get from the pithy VB6 code being able to read and write in one swift, decisive operation. Beautiful!
2 comments:
I was able to find good info from your articles.
Good post. I'm dealing with some of these issues as
well..
Post a Comment