There are many ways to do this and I'm not sure which is the best for your case.
If you can and want to create strictly fixed size records you could go for seeking the right position directly. This may be faster for large quantities of data.
Or you could rely on the BinaryWriter to prefix each string with two length bytes and then read the right number of characters..
If you want to stay more flexible and keep things simple you could go for serializing with a BinaryFormatter
:
Create a serializable class:
[Serializable]
public class MyClass
{
public string Name;
public int Number;
}
Then you can write a number of instances to disk using a BinaryFormatter
:
string fileName = "yourfileName";
FileStream stream = new FileStream(fileName,
FileMode.Append, FileAccess.Write, FileShare.Write);
var formatter = new BinaryFormatter();
formatter.Serialize(stream, new MyClass() { Name = "A", Number = 12365 });
formatter.Serialize(stream, new MyClass() { Name = "B", Number = 2365 });
formatter.Serialize(stream, new MyClass() { Name = "C", Number = 365 });
stream.Close();
And read it back, maybe in a List<T>
, still using the same formatter:
FileStream stream2 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
List<MyClass> myClassList = new List<MyClass>();
while (stream2.Position < stream2.Length)
myClassList.Add((MyClass)formatter.Deserialize(stream2));
Now you can access myClassList[2]
..
Update:
Looks like you can do this as well, as long as you are sure about the record length:
using (BinaryWriter binWriter = new BinaryWriter(File.Open(fileName, FileMode.Create)))
{
binWriter.Write("RAller");
binWriter.Write(123);
binWriter.Write("RoBler");
binWriter.Write(23);
binWriter.Write("RolCer");
binWriter.Write(3);
binWriter.Write("RolDDr");
binWriter.Write(423);
binWriter.Write("REEler");
binWriter.Write(523);
binWriter.Write("RFFler");
binWriter.Write(66);
}
using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
{
// string < 255 seems to get only a one byte length prefix:
int recLen = 1 + 6 + 4;
br.BaseStream.Seek(recLen * 3, SeekOrigin.Begin);
string s = br.ReadString();
int i = br.ReadInt32();
}
Short strings only get a one byte length counter:
Longer strings get the two byte prefix and for variable sizes you would have to step through the records, calculating the next offset.
I can't really image why you would want that, unless the data are really large.
Well, requirements sometimes are what they are and sometimes they require questioning..
BinaryFormatter
and serializing the data. See here – Gossamer