Strange "IOException was unhandled" - vb.net

(VB.NET, .NET 3.5)
I wrote the following function to read some text from txt file. It was working fine but now it's not. It keeps giving me this error message
"IOException was unhandled" and
" The process cannot access the file 'F:\kh_matt\ch1.txt' because it is being used by another process."
The ch1.txt is not even opened or being used by any program at all. I tried to move ch1.txt to another location (Drive D) still I got the same message error but just different location it says The process cannot access the file 'D:\ch1.txt' because it is being used by another process."
Here's my code block :
Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click
Dim reader As StreamReader
Dim filelocation As String
filelocation = "F:\kh_matt\ch1.txt"
Dim chid As Integer
chid = 1
If System.IO.File.Exists(filelocation) = True Then
reader = New StreamReader(New FileStream(filelocation, FileMode.Open))
Else
MsgBox(filelocation, MsgBoxStyle.OkOnly)
End If
Dim MyStream As New StreamReader(Path.Combine(Application.StartupPath, filelocation))
Dim vArray() As String = MyStream.ReadToEnd.Split(CChar("$"))
MyStream.Close()
Dim count As Integer
For d As Integer = 0 To vArray.Length - 1 Step 1
If d = vArray.Length - 1 Then
Exit For
End If
InsertKh(chid, d + 1, vArray(d))
count = d + 1
Next
MsgBox("Done Inserting")
End Sub
It always points to this code :
Dim MyStream As New StreamReader(Path.Combine(Application.StartupPath, filelocation))
Where I debug and press the respective button. Can anyone point out what the problem is ? Thanks

I think this is your problem:
If System.IO.File.Exists(filelocation) = True Then
reader = New StreamReader(New FileStream(filelocation, FileMode.Open))
If the file exists it will open a StreamReader on it, then try and open another StreamReader on the same file, which will lock the file, causing this line:
Dim MyStream As New StreamReader(Path.Combine(Application.StartupPath, filelocation))
to fail.
Also, some pointers:
consider using the System.IO.File.ReadAllText() method instead, much easier
if you must use streams, wrap them in a using block to ensure they're freed correctly, for example:
`
Dim vArray() As String
using (Dim MyStream As New StreamReader(Path.Combine(Application.StartupPath, filelocation))
{
vArray = MyStream.ReadToEnd.Split(CChar("$"))
}
(sorry if the above code isn't 100% correct, I don't write much VB.Net)

It seems you open the file twice, which is probably what's causing your error:
reader = New StreamReader(New FileStream(filelocation, FileMode.Open))
...
Dim MyStream As New StreamReader(Path.Combine(Application.StartupPath, filelocation))
Are you sure that's what you intend to do? It looks like you can remove MyStream and use reader instead. Also, you don't have to use Path.Combine, since filelocation is not relative.

Make sure that you close your stream & streamreader once you've finished reading the file, even when an exception is being thrown.
Use a try/finally block, and close the stream / streamreader in the finally block.

Thanks all for the reply. It's my mistake. I forgot to comment out my code that I wrote for testing earlier. After commenting this code out it works like before.
'If System.IO.File.Exists(filelocation) = True Then
' reader = New StreamReader(New FileStream(filelocation, FileMode.Open))
'Else
' MsgBox(filelocation, MsgBoxStyle.OkOnly)
'End If
Have a good day.

Related

VB.NET 2010 - Process.Start("filePath\Test.bat") not opening test.bat?

I have been working on some vb.net 2010 coding and I am stuck on a piece of code that I dont know how to fix it, so thats why I ask you to maybe help me with this code.
Code:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim url As New System.Uri("http://example/one/")
Dim req As System.Net.WebRequest
req = System.Net.WebRequest.Create(url)
Dim resp As System.Net.WebResponse
Dim filePath As String
filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\examplepath"
Try
resp = req.GetResponse()
resp.Close()
req = Nothing
Process.Start("filePath\Test.exe")
Catch ex As Exception
req = Nothing
Me.Close()
End Try
End Sub
Problem:
The file in %APPDATA%\ExamplePath\Test.bat doesn't open.
I hope you can help me :)
This line seems the problem:
Process.Start("filePath\Test.exe")
Here you're putting a variable as a string, which of course won't work. Instead, concatenate it with the file name:
Process.Start(filePath & "\Test.exe")
That will work, but a better way to handle the file system is to use the Path class and the Combine method to handle a path that has multiple parts:
Process.Start(Path.Combine(filePath, "Test.exe"))
This deals with putting the correct separator and the fact that it may or may not have a trailing backslash.
You need to use cmd for opening batfiles:
Process.Start("cmd", "/c foobar/test.bat")
be carefull, if the filepath contains spaces you have to add extra "" to make it work:)
your problem was, that a .bat file is not a process to start, only a file
Try declaring a new process and specify the WorkingDirectory property.
Use the following code to achieve this
Dim myProcess As New Process
myProcess.StartInfo.WorkingDirectory = Environment.GetFolderPath(SpecialFolder.ApplicationData)
myProcess.StartInfo.FileName = "Test.bat"
myProcess.Start()

Can't Multi Download With WebClient

I know this question has been asked before, but I have a special way I want to download the files through a webclient, I want to download each file at a time through a Do While statement, but it just adds the file to download and moves on to the next task that also downloads another file so it cancels each other out and crashes the application.
Private Function StartDownloads()
Dim wc As New WebClient
AddHandler wc.DownloadProgressChanged, AddressOf DownloadProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf DownloadFileCompleted
Dim delimiterChars As Char() = {"+"c}
Dim words As String() = RichTextBox1.Text.Split(delimiterChars)
Dim i As Integer = 1
Do While (i < words.Length)
Dim delimiterChars1 As Char() = {"|"c}
Dim words1 As String() = words(i).Split(delimiterChars1)
Dim name As String = words1(0)
Dim fileurl As String = words1(2)
ToolStripStatusLabel1.Text = "Downloading " & name & ":"
wc.DownloadFileAsync(New System.Uri(fileurl), Path.GetTempPath() & "\" & name)
i = (i + 1)
Loop
End Function
AND
Private Sub DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
ProgressBar1.Value = e.ProgressPercentage
ToolStripStatusLabel2.Text = String.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024D / 1024D).ToString("0.00"),
(e.TotalBytesToReceive / 1024D / 1024D).ToString("0.00"))
End Sub
So basically in the Do While statement it starts the download then continues without waiting for the download to finish and then downloads both at once, which then crashes the program/interferes with the labels displaying the download name, the reason this is a different question from others is I need it to specify the download name as I can't do with other tutorials, by adding the downloads to a list...
So if anyone can help me make the Do While statement wait for the download to finish then continue with the next without loosing the file name and stuff like that, please give me some tips, thanks!
I know that DownloadFile waits for the download to finish then continues, but I need it to show download progress and download bytes and stuff like that...
P.S. Sorry if this is confusing as it's hard to explain, thanks.
By adding await wc.DownloadFileTaskAsync(...), it worked perfectly

Separating large file and inserting carriage returns based on string

New to VB.Net but a friend recommended that I used it for what I'm trying to do. I have a huge text file and I want to insert carriage returns in after a specific string.
Apart from the mess I have below , how would I alter this to read a file and then once we see the text "ext" insert a new line feed. I'm expecting one of the lines in the input file to produce alot of carriage returns.
Currently what I have managed to mock together below reads an input file until end of line and writes it out again into another file.
Module Module1
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Catch e As Exception
' Let the user know what went wrong.
Console.WriteLine("The file could not be read:")
Console.WriteLine(e.Message)
End Try
Console.ReadKey()
End Sub
Changes made following comments.. Falling over at 500mb files due to memory constraints:
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
Dim term As String = "</ext>"
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
line = line.Replace(term, term + Environment.NewLine)
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Since your lines are very big, you'll have to:
Read/Write one character at a time
Save the last x characters
If the last x characters are equal to your term, write a new line
Dim term As String = "</ext>"
Dim lastChars As String = "".PadRight(term.Length)
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Using sr As New System.IO.StreamReader("C:\My Documents\input.txt")
While Not sr.EndOfStream
Dim buffer(1) As Char
sr.Read(buffer, 0, 1)
lastChars &= buffer(0)
lastChars = lastChars.Remove(0, 1)
sw.Write(buffer(0))
If lastChars = term Then
sw.Write(Environment.NewLine)
End If
End While
End Using
End Using
Note: This will not work with a Unicode file. This assume each characters are one byte.

Loaded file not generating in a listview - vb.net

I am trying to write a program that can load multiple different text files, containing encrypted values, individually to create a ListView of the encryptions is the first column and the decrypted value in the second column. The problem that I am running into is that when I load a file... nothing happens. There is no error, no crash, just nothing. I believe that it is not reading the file path correctly, but I am very new to this so that is only intuition. Here is my code:
Private Sub loadBtn_Click(sender As System.Object, e As System.EventArgs) Handles loadBtn.Click
valueList.Clear()
valueList.Columns.Add("Encypted File", 150)
valueList.Columns.Add("Decrypted", 100)
Dim newFile As New OpenFileDialog()
Try
If newFile.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim writer As New System.IO.StreamReader(newFile.FileName)
Dim line() As String
Do Until writer.Peek <> -1
Dim newLine As ListViewItem
line = writer.ReadLine.Split("="c)
newLine.Text = line(0).ToString
valueList.Items.Add(newLine)
newLine.SubItems.Add(Crypto.AES_Decrypt(line(0)))
Loop
writer.Close()
End If
Catch ex As Exception
valueList.Items.Add("Error reading file." & ex.Message)
End Try
End Sub
There is a notification in the line
newLine.Text = line(0).ToString
that the variable 'newLine' is used before it has been assigned a value. I thought that I was assigning it a value at that time but I guess I am wrong. This does not cause a runtime error, just thought I should make not of it.

Cannot write to a file after reading it with IO.StreamReader

I am making an encryption program that also functions as a notepad (CryptoMatic). There is a Open function with the following code:
Dim r As New StreamReader(filename)
Dim text As String = r.ReadToEnd
txtFileContents.text = text
r.Dispose()
r.Close()
Now there is the save and save as button
the save button checks if the file had been saved previously or not. If yes then I am trying to write to that file with the following code:
Dim myFileStream As New System.IO.FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None)
myFileStream.Lock(0, 100)
Dim myWriter As New System.IO.StreamWriter(myFileStream)
myWriter.WriteLine(text)
myWriter.Flush()
myWriter.Close()
myFileStream.Close()
myFileStream.Unlock(0, 100)
Now when i press the save button it gives the following error:
The process cannot access the file 'C:\Users\VisualTech\Documents\Visual Studio 2010\Projects\CryptoMatic Update\CryptoMatic Update\bin\Debug\text.txt' because it is being used by another process.
and the application stops, can anyone please help me?
I have tried your code above and have noticed two things:
You don't need a myFileStream.Lock call because you already open it
with FileShare.None
You can't call myFileStream.Unlock(0, 100) after the call to
myFileStream.Close()
So I have rewritten your code in this way.
Sub Main
Dim text = "This is a text to write in the stream"
Using myFileStream As New System.IO.FileStream("D:\temp\testlock.txt", FileMode.Append, FileAccess.Write, FileShare.None)
Using myWriter As New System.IO.StreamWriter(myFileStream)
myWriter.WriteLine(text)
End Using
End Using
End Sub