Finding a specific value when using BinaryWriter

It's hard for me to express myself, so I will go straight to the code

FileStream stream = new FileStream("//ignoreThis//demo.bin", FileMode.Append, FileAccess.Write, FileShare.Write)); BinaryWriter writer = new BinaryWriter(stream); writer.Write(myNum); writer.Write(myString); 

I can call this method several times, and I know that every time I do this, it will add new data to the end of the "demo.bin" file. Now I'm trying to write a method where I can access my third instance (I'm not sure if I can call it). The main problem is that the variables are of different sizes, although I use this code to make String “fixed” with a length of 20 (I know that this does not work when someone writes a string longer than 20, but I already wrote a confirmation to make sure they do not exceed this limit)

Here is the code that I use to make String a constant length

 public String MakeFixedSize(int length, String inputString) { return inputString.PadRight(length, '\0'); } 

As far as I know, int has a fixed size as well as a long one that I use in this program (not in the code above)

0
seek fixed-size-types
Oct 31 '15 at 18:08
source share
1 answer

There are many ways to do this, and I'm not sure what is best for your business.

If you can and want to create records of a strictly fixed size, you can search for the correct position directly. It can be faster for large amounts of data.

Or you can rely on BinaryWriter to prefix each line with two bytes of length, and then read the correct number of characters.

If you want to stay more flexible and keep everything in order, you can go for serialization using BinaryFormatter :

Create a serializable class:

 [Serializable] public class MyClass { public string Name; public int Number; } 

Then you can write multiple instances to disk using 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, possibly in 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:

It looks like you can do this too if you are sure about the length of the record:

 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 lines only get a byte length counter:

enter image description here

Longer strings get a two-byte prefix and for variable sizes you will need to go through the records, calculating the next offset.

I cannot understand why you would like this, if only the data is really big.

Well, sometimes the requirements are what they are, and sometimes they require a survey.

0
Oct 31 '15 at 19:44
source share



All Articles