Using System.IO.StreamWriter to write another line - vb.net

I need to update the students score with a new score but I cant get it to write to the line that the students current score it at. It just deletes the whole text.
Alex,letmein,0
David,qwerty1,0
John,password,0
Paul,lion,0
Luke,bennett,0
Ronald,Mcdonald,0
Erin,german,0
Laura,Scotland,0
Ross,extra,0
Alan,beverage,0
Try
fileName = "C:\Documents and Settings\Student\Desktop\Task10\primary4.txt"
Dim sWriter As New System.IO.StreamWriter(fileName)
index = lblPosition.Text
sWriter.Write(username(index))
sWriter.Write(",")
sWriter.Write(password(index))
sWriter.Write(",")
sWriter.WriteLine(updatescore(position)
sWriter.Close()
MessageBox.Show("Writing file to disk")
Me.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try

You cannot update a specific line in a text file. You can only rewrite a text file from scratch or append to it. Which is not what you want here.
You have to use File.ReadAllLines() to get a string[] with the lines in the text file. Search the specific element in the array that you want to update. Then write it all back with File.WriteAllLines().
This is expensive of course, but your text file is small. This is the primary reason why database engines are popular.

I see at least one additional bug in here (an exception would result in leaving the file open). You should do something like this instead:
fileName = "C:\Documents and Settings\Student\Desktop\Task10\primary4.txt"
Dim sWriter As IO.StreamWriter
Try
sWriter = New IO.StreamWriter(fileName, True)
index = lblPosition.Text
sWriter.Write(username(index))
sWriter.Write(",")
sWriter.Write(password(index))
sWriter.Write(",")
sWriter.WriteLine(updatescore(position)
MessageBox.Show("Writing file to disk")
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
sWriter.Close()
End Try
Me.Close()

Related

Log Writer not creating new line for each entry

I get the feeling this is something really simple, but I've tried I don't know how many permutations of vbNewLine, Environment.NewLine, sMessage & vbNewLine (or Environment.Newline) I've tried, or how many pages on this site, or through Google I've looked at but nothing has worked.
I even tried getting help from a VB.Net discord channel I'm a part of and they suggested to do the same things that I've done and the procedure is still writing each new log entry at the end of the previous one in a continuous string. My writer is below. Am I missing something simple?
Edit: The code that worked is below in case anyone else comes along with the same issue. If you want to see the original code it's in the edit log.
Option Explicit On
Imports System.IO
Public Class WriteroLog
Public Shared Sub LogPrint(sMessage As String)
Dim AppPath As String = My.Application.Info.DirectoryPath
If File.Exists($"{AppPath}\Log.txt") = True Then
Try
Using objWriter As StreamWriter = File.AppendText($"{AppPath}\Log.Txt")
objWriter.WriteLine($"{Format(Now, "dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
objWriter.Close()
End Using
Catch ex As Exception
MsgBox(ex)
Return
End Try
Else
Try
Using objWriter As StreamWriter = File.CreateText($"{AppPath}\Log.Txt")
objWriter.WriteLine($"{Format(Now, "dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
objWriter.Close()
End Using
Catch ex As Exception
MsgBox(ex)
Return
End Try
End If
End Sub
End Class
The File.AppendText() method creates a new StreamWriter that is then used to append Text to the specified File.
Note, reading the Docs about this method, that you don't need to verify whether the File already exists: if it doesn't, the File is automatically created.
As a side note, when creating a Path, it's a good thing to use the Path.Combine method: it can prevent errors in the path definition and handles platform-specific formats.
Your code could be simplified as follows:
Public Shared Sub LogPrint(sMessage As String)
Dim filePath As String = Path.Combine(Application.StartupPath, "Log.Txt")
Try
Using writer As StreamWriter = File.AppendText(filePath)
writer.WriteLine($"{Date.Now.ToString("dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
End Using
Catch ex As IOException
MsgBox(ex)
End Try
End Sub
The File.CreateText does not assign result to "objWrite", should be:
objWriter = File.CreateText($"{AppPath}\Log.Txt")
Not really sure if this is the root of your problem, but it is an issue.
In essences, your logic is re-opening or creating the stream "objWriter" for every call to this method. I would recommend you initialize "objWriter" to Nothing and only define if it is Nothing.
Set to Nothing as below.
Shared objWriter As IO.StreamWriter = Nothing
Then add check for Nothing in logic.

vb.net resaving binary files

I have the following method to save Custom As List of (CustomItem)" to a binary file:
Dim st As FileStream
Try
If Not Directory.Exists(Path.GetDirectoryName(FilePath)) Then Directory.CreateDirectory(Path.GetDirectoryName(FilePath))
st = File.Open(FilePath, FileMode.OpenOrCreate)
Dim SerialObj As New BinaryFormatter()
SerialObj.Serialize(st, Custom)
st.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
This doing great and I can read the content but after changing a string property in the "CustomItem" class and saving the file again it saves the file without any issues. But the issue appears when I read the file again it gets that the file has zero "CustomItem"(s) but it has at least 3 "CustomItem"s inside the file.
Sorry for lengthiness,
but what can be the issue?

Opening a notepad from a button in VB.net

I want to create a button in VB.net that lets me browse my hard drive for the specified notepad file i want to open and retrieve the contents from it, i only have tried using FileStream and StreamReader but this wont let me manually select the notepad file instead i have to declare a default filename. Any sample codes would be appreciated thanks in advance, i just need a starting point. I am really stuck to this.
This the code i am using right now, but i have to specify the correct file name on it:
Dim fStream As New System.IO.FileStream("messages.txt", IO.FileMode.Open)
Dim sReader As New System.IO.StreamReader(fStream)
Dim Index As Integer = 0
Do While sReader.Peek >= 0
ReDim Preserve sArray(Index)
sArray(Index) = sReader.ReadLine
Index += 1
Loop
If I understand your question correctly, you want to have an option to choose which textfile to open, if so you can try this:
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "c:\"
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
stream = openFileDialog1.OpenFile()
If (stream IsNot Nothing) Then
//do your loop here
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message)
Finally
If (stream IsNot Nothing) Then
stream.Close()
End If
End Try
End If
I think you may be using the wrong approach with a FileStream. Instead look to allow a user to select a file, then use Process.Start to open Notepad.
Take a look here for examples on selecting a file. The page here then details Process.Start.
I'm happy to provide more code samples directly here, but those two pages should be sufficient.

Why am I getting object reference not set error on script task connector?

I have an SSIS package (SQL Server 2005) that loops through a bunch of flat files in a folder. I need to wait until the source application has finished writing the file before I can open it in my flat file import task.
I have a For Each loop container and within it a script task to execute before the Data Flow Task.
When I try to create the success connector between the Script Task and the Data Flow Task I get this error:
Could not create connector. Object reference not set to an instance of
an object.
I get that something is being set to nothing, but I can't see it. I have DelayValidation set to true on both the Script Task and the Data Flow Task. What else am I missing?
I'm a C# guy so maybe I'm missing something obvious in the VB. Here's the script I poached from the interwebs:
Public Sub Main()
Dim strFileName As String = CType(Dts.Variables("FileName").Value, String)
Dim objFS As System.IO.FileStream
Dim bolFinished As Boolean = False
Do
Try
objFS = System.IO.File.Open(strFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
bolFinished = True
objFS.Close()
Catch ex As Exception
System.Threading.Thread.Sleep(1000)
End Try
Loop
If bolFinished Then
Dts.TaskResult = Dts.Results.Success
Else
Dts.TaskResult = Dts.Results.Failure
End If
End Sub
Milen k is more than right. It looks like you have an infinite loop which is opening a file several times until it breaks down.
You could change your code with the below suggested code. This will help you to get out of the infinite loop.
Your current code:
Do
Try
objFS = System.IO.File.Open(strFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
bolFinished = True
objFS.Close()
Catch ex As Exception
System.Threading.Thread.Sleep(1000)
End Try
Loop
Suggested code:
Do While(true)
Try
objFS = System.IO.File.Open(strFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
bolFinished = True
objFS.Close()
Exit Do
Catch ex As Exception
System.Threading.Thread.Sleep(1000)
End Try
Loop
Make sure that you have created a Flat File Source for your Data Flow task. If you do not have an existing one, create a temporary one which act as a place-holder for the file paths you feed it through the For Each loop.
From what I understand, you should be passing the path to each file that you will be importing to your Flat File Connection. This can easily be done by adding the variable generated in your For Each loop as an expression in the Expression property of your Flat File Connection.
UPDATE:
You need to set a condition in your Do ... Loop. For example: Loop While Not bolFinished. Look at this document for more information.

VB.Net - Writing to textfile from a textbox

Hey guys, just another little problem here! Trying to write a quiz for a college portfolio and having trouble with writing to a .txt textfile. On one form(form4.vb), I have a listbox that picks up the information held within a notepad textfile called "usernames" which contains names of quiz users. When written in manually to this textfile, my listbox picks it up fine, however, on a different form(form3.vb), I have a textbox where a user inputs their name, this is supposed to go to the "usernames.txt" textfile to be picked up by the listbox on the other form but instead, it does not write anything at all and if there is already text on this textfile, it wipes it all out.
I also have to use the application.startup path instead of the usual C:\my documentents\ etc so i would have to begin with something like this: (Note: code is a little mixed up due to messing around with different variations but this is just a example)
'Try
' Dim appPath As String
' Dim fileName As String
' appPath = Application.StartupPath
' fileName = appPath & "\usernames.txt"
' sWriter = New System.IO.StreamWriter(fileName)
' sWriter.Close()
' MessageBox.Show("Writing file to disk")
'Catch ex As Exception
' MessageBox.Show("File Access Error", "Error")
'End Try
'MessageBox.Show("Program terminating")
'Application.Exit()
Hope someone can help! =)
You want something more like this:
Dim appPath As String = Application.StartupPath
Dim fileName As String = IO.Path.Combine(appPath, "usernames.txt")
Try
IO.File.AppendAllText(fileName, TextBox1.Text & Environment.NewLine)
Catch ex As Exception
MessageBox.Show("File Access Error", "Error")
End Try
MessageBox.Show("Program terminating")
Environment.Exit()
Some things worth noting in this code:
Path.Combine() as the correct way to add the separator character
File.AppendAllText() is much easier for simple things than messing with streamreader/writer. Pair it with File.ReadAllText() or File.ReadAllLines() in the other direction.
Environment.Exit() vs Application.Exit()
Where is your dim statement for sWriter (streamWriter)?