Ajwad J Ajwad J -4 years ago 148
Vb.net Question

I cant write data to a binary file in a loop

All of my data (name/rollnumber/class) is of a fixed length (14 bytes), I want the program to keep taking a random name from the array, then make a random rollnumber and keep writing it into a file until I press "A".

After i finish running the program, the first 14 bytes are always empty and then my data is in the next 14 bytes. Nothing more nothing less. I don't know why it only wrote one data record.

This is my code:

Dim randomvalue As Integer

'Making this array so that each data entry has 14 bytes to it

Dim array1(91) As Integer

array1(1) = 14
For x = 2 To 91
array1(x) = array1(x) + 14
Next

Dim n1, n2, n3, n4 As Integer

'Array with names of fixed lenght, I want to take a name from only these 9:

Dim array2(9) As String
array2(1) = "aleen"
array2(2) = "talha"
array2(3) = "waddi"
array2(4) = "hasna"
array2(5) = "hassa"
array2(6) = "zainn"
array2(7) = "faqeh"
array2(8) = "furru"
array2(9) = "ibrah"

'There is a structure above submain with studentname/rollnumber/class all declared as string

Dim newstudent As student
Dim studentstream As New FileStream("C:\Users\Students\Desktop\A2Filing.dat", FileMode.OpenOrCreate)
Dim bw As New BinaryWriter(studentstream)

While Console.ReadLine <> "A"
Console.WriteLine("Press any key other than 'A' if you want to make another entry into the file")


'CInt(Math.Floor((upperlimit - lowerlimit + 1) * Rnd())) + lowerlimit
'Randomize a number b/w 1-9 to get a studentname from the array

randomvalue = CInt(Math.Floor((9 - 1 + 1) * Rnd())) + 1
newstudent.studentname = array2(randomvalue)

n1 = Rnd() + (Rnd() * 50)
n2 = Rnd() * 10
n3 = Rnd() * 255
n4 = Rnd() * Rnd()
newstudent.rollnumber = Convert.ToString(Left(n1, 1) + Left(n2, 1) + Left(n3, 1) + Left(n4, 1))

newstudent.studentclass = "A2"

'Randomize a number between 91 and 1 to place the data in

Dim randomvalue2 As Integer
randomvalue2 = CInt(Math.Floor((91 - 1 + 1) * Rnd())) + 1
studentstream.Position = array1(randomvalue2)


bw.Write(newstudent.studentname)
bw.Write(newstudent.rollnumber)
bw.Write(newstudent.studentclass)
End While

Answer Source

There are some notes here:

  • the array1 items as you init will all be 14, you have to change it to following, but as i'll say later it is not required to define such array!

    For x = 2 To 91
      array1(x) = array1(x - 1) + 14   'modified to array1(x - 1)
    Next
    
  • before bw.Write, you have this: studentstream.Position = array1(randomvalue2) which will override the file position! also all items in array1 are equal to 14. this is why you get always a small file size (nothing more nothing less). you don't need to set position this way. Just remove that line from your code to append data one after one.

  • According to documentations, if you use a BinaryWriter to write strings, it will be prefixed by string-length! see this question.

    Dim bw As New BinaryWriter(studentstream, System.Text.Encoding.ASCII)
    
    bw.Write("A")  'writes: 1 A  => where 1 is length of string "A"
    bw.Write("BC") 'writes: 2 B  => where 2 is length of string "BC" 
    
    'note that for Unicode Encoding, it will be 2 bytes per char
    Dim bw As New BinaryWriter(studentstream, System.Text.Encoding.Unicode)
    bw.Write("A")  '2 A 0        where 2 is length of unicde string [A 0]
    bw.Write("BC") '4 B 0 C 0    where 4 is length of unicde string [B 0 C 0]
    
  • If you want to write strings without length prefix, you can use System.Text.Encoding.ASCII.GetBytes(str) to convert it to byte array:

    bw.Write(System.Text.Encoding.ASCII.GetBytes(newstudent.studentname))
    
  • Another option will also be to use StreamWriter instead of BinaryWriter as it seems you don't need it. see this link

  • note that its better to open files with Using block. otherwise, do not forget to call Close method (studentstream.Close()) when you finished. if you don't do this, you may lose last chunk or whole of your data!

    Using studentstream As New FileStream("C:\...\Desktop\A2Filing.dat", FileMode.Create)
    
  • use FileMode.Create to override the file if it already exists

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download