SaveFileDialog.OpenFile() IndexOutofRangeException - vb.net

I recently wrote some code related to a menu strip bar, there is an option contains OpenFile, SaveFile and Exit etc. Following is the code.
Dim myStream As Stream
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Filter = "ebd files (*.txt)|*.txt"
saveFileDialog1.FilterIndex = 2
saveFileDialog1.RestoreDirectory = True
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
Try
myStream = saveFileDialog1.OpenFile()
If (myStream IsNot Nothing) Then
' Code to write the stream goes here.
Dim sw As New StreamWriter(myStream)
sw.Flush()
sw.Close()
myStream.Close()
End If
Catch Ex As Exception
MessageBox.Show("Can't save file on disk: " & Ex.Message)
End Try
End If
another chunk of code exactly same but withou If statement, as following,
Dim myStream As Stream
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Filter = "ebd files (*.txt)|*.txt"
saveFileDialog1.FilterIndex = 2
saveFileDialog1.RestoreDirectory = True
Try
myStream = saveFileDialog1.OpenFile()
If (myStream IsNot Nothing) Then
' Code to write the stream goes here.
Dim sw As New StreamWriter(myStream)
'some sw.WriteLine code here...
sw.Flush()
sw.Close()
myStream.Close()
End If
Catch Ex As Exception
MessageBox.Show("Can't save file on disk: " & Ex.Message)
End Try
The problem I have is the second piece of code, when it runs the system will throw out index out of range exception, How can I fix it without using a If statement? Is there any method to show the dialog window anyway? Anyone can give me clue on this index error message? Thanks!

Looking at the source code of OpenFile reveals the possible point of error
public Stream OpenFile()
{
IntSecurity.FileDialogSaveFile.Demand();
string str = base.FileNamesInternal[0];
if (string.IsNullOrEmpty(str))
{
throw new ArgumentNullException("FileName");
}
Stream stream = null;
new FileIOPermission(FileIOPermissionAccess.AllAccess, IntSecurity.UnsafeGetFullPath(str)).Assert();
try
{
stream = new FileStream(str, FileMode.Create, FileAccess.ReadWrite);
}
finally
{
CodeAccessPermission.RevertAssert();
}
return stream;
}
It seems that the code try to get the base.FileNamesInternal[0]; but if you don't show the dialog or choose a file name to save this internal array is probably empty.
I have tried to read the item at index zero in the property FileNames and I get the same error
string file = saveFileDialog1.FileNames(0) ' Index out of range....
I would like to hear from our WinForms more experienced posters if this is really what it seems

I guess I'm a bit confused about what you are trying to accomplish.
In the second example it seems you never 'show the dialog' ie saveFileDialog1.ShowDialog()
Thus the user cannot select a file/path
Then you attempt to use the file/path that has not been set
http://msdn.microsoft.com/en-us/library/system.windows.forms.savefiledialog.openfile.aspx
If you just need to open an arbitrary file for write without showing the user the dialog why not just use File.Open() or something?
http://msdn.microsoft.com/en-us/library/b9skfh7s.aspx

Related

Skipping a line of code if an image isn't selected

If a user selects an image it will save the image as per the below code:
PictureBox1.Image.Save(PicFile, System.Drawing.Imaging.ImageFormat.Jpeg)
Now if the user decides not to select an image, is there a way to skip this code? I currently get the following error:
Additional information: Object reference not set to an instance of an object.
This is what I've tried:
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(.jpg;.png;*.gif)|*.jpg;*.png;*.gif"
If opf.ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(opf.FileName)
End If
Try
Dim ms As New MemoryStream
PictureBox1.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
Dim img As Byte()
img = ms.ToArray()
DataGridView1.Rows.Add(img)
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
Now if the user decides not to select an image, is there a way to skip this code?
If by this you mean the user selects Cancel, then yes. Simply place the Try[...]Catch block into your If statement and it will only attempt the code if the user selects Open.
Something like this:
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(.jpg;.png;*.gif)|*.jpg;*.png;*.gif"
If opf.ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(opf.FileName)
Try
Dim ms As New MemoryStream
PictureBox1.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
Dim img As Byte()
img = ms.ToArray()
DataGridView1.Rows.Add(img)
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
End If
If you only wanted to skip certain bits of code you could do a check on opf.FileName. As an example:
If opf.FileName <> "" Then
PictureBox1.Image = Image.FromFile(opf.FileName)
End If

Program freezes when opening a textfile with over 100,000 lines

My code lets the user open a text file and the contents of the textfile per line is being placed inside an array, but my program freezes when the contents of the textfile has over 100,000 lines or more. I have tried backgroundworker but it seems not to support OpenFileDialog.
It runs fine on 1,000 lines or less, but i need over 100,000 lines of text for this program.
Is there any way to tweak its performance so it won't freeze?
here is my code:
Dim Stream As System.IO.FileStream
Dim Index As Integer = 0
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "D:\work\base tremble"
openFileDialog1.Filter = "txt files (*.txt)|*.txt"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
Stream = openFileDialog1.OpenFile()
If (Stream IsNot Nothing) Then
Dim sReader As New System.IO.StreamReader(Stream)
Do While sReader.Peek >= 0
ReDim Preserve eArray(Index)
eArray(Index) = sReader.ReadLine
RichTextBox3.Text = eArray(Index)
Index += 1
'Delay(2)
Loop
Label1.Text = "0/" & eArray.Length & ""
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message)
Finally
If (Stream IsNot Nothing) Then
Stream.Close()
End If
End Try
End If
End Sub
A backgroundWorker shouldn't have any UI in it.
What you need to do is:
Prompt for the filename in your main UI
create the stream in BackgroundWorker.DoWork
get rid of the array / redim array and use a StringCollection - you can convery it to an array at the end if you really want one.
raise any events through the BackgroundWorker.RunWorkerCompleted
Avoid redim preserve if you can, it's horrible.

Storing a selected notepad its contents to FileStream

I am currently having problems in storing the contents of any selected notepad file from openFileDialog to the FileStream. My code states a default filename as i do not know how to revise the FileStream code, i want it to register the filename of my selected notepad.
By default it would only read the contents of "messages.txt", i want to have a freedom to choose any notepad file and retrieve the data from it. Any kind of help or advice will do thanks in advance.
here is my code:
Dim Stream As New System.IO.FileStream("messages.txt", IO.FileMode.Open)
'i need to do something about this line above
Dim sReader As New System.IO.StreamReader(Stream)
Dim Index As Integer = 0
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "D:\work"
openFileDialog1.Filter = "txt files (*.txt)|*.txt"
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 While sReader.Peek >= 0
ReDim Preserve eArray(Index)
eArray(Index) = sReader.ReadLine
RichTextBox3.Text = eArray(Index)
Index += 1
Delay(2)
Loop
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message)
Finally
If (Stream IsNot Nothing) Then
Stream.Close()
End If
End Try
End If
End Sub
I rearranged your code just a bit. Basically you were creating a stream, and then creating the reader for the stream to "messages.txt". Later you set the stream object to a new stream based on the OpenFile method of the file open dialog. But your reader was still pointing to the first stream you opened, so that is what was getting read. I've changed the code below to not open that first stream, and to create the reader after you have created the stream based on the file the user selected.
'don't create a stream hear and the reader, because you are just recreating a stream later in the code
Dim Stream As System.IO.FileStream
Dim Index As Integer = 0
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "D:\work"
openFileDialog1.Filter = "txt files (*.txt)|*.txt"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
'This line opens the file the user selected and sets the stream object
Stream = openFileDialog1.OpenFile()
If (Stream IsNot Nothing) Then
'create the reader here and use the stream you got from the file open dialog
Dim sReader As New System.IO.StreamReader(Stream)
Do While sReader.Peek >= 0
ReDim Preserve eArray(Index)
eArray(Index) = sReader.ReadLine
RichTextBox3.Text = eArray(Index)
Index += 1
Delay(2)
Loop
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message)
Finally
If (Stream IsNot Nothing) Then
Stream.Close()
End If
End Try
End If
End Sub

The process cannot access the file because it is being used by another process.-error while writing to a file in vb.net

in my vb.net code im using streamwriter to write to a file that has been given as input to the form.
Dim strContents As String
Dim objReader As StreamReader
Try
objReader = New StreamReader("C:\test.txt")
strContents = objReader.ReadToEnd()
objReader.Close()
Catch Ex As Exception
End Try
Dim Contents As String
Dim bAns As Boolean = False
Dim objWriter As StreamWriter
Dim FileStream As System.IO.FileStream
Try
FileStream = New FileStream("C:\test.txt", FileMode.Open, FileAccess.ReadWrite)
objWriter = New StreamWriter("C:\test.txt")
objWriter.Write("fdgdfgdjkljljklg")
objWriter.Close()
bAns = True
Catch Ex As Exception
End Try
in some of the systems its working fine but in some other workstations its showing error that mentioned in the subject.
What restricts the access to the file here?
can anyone help me on this?
What restricts the access to the file here?
The fact that you haven't disposed the stream and thus the process is locking the file. A StreamWriter is holding an unmanaged handle to the file. If you don't dispose this handle other threads/process cannot open the file.
I would recommend you to always wrap IDisposable resources in Using statement to ensure proper disposal (even if an exception is thrown inside the block):
Using filestream As New StreamWriter(Inifile, True, System.Text.Encoding.UTF8)
' ... use the filestream here to write to the file
End Using

Creating and appending text to txt file in VB.NET

Using VB.NET, I am trying to create a text file if it doesn't exist or append text to it if exists.
For some reason, though it is creating the text file I am getting an error saying process cannot access file.
And when I run the program it is writing text, but how can I make it write on a new line?
Dim strFile As String = "C:\ErrorLog_" & DateTime.Today.ToString("dd-MMM-yyyy") & ".txt"
Dim sw As StreamWriter
Dim fs As FileStream = Nothing
If (Not File.Exists(strFile)) Then
Try
fs = File.Create(strFile)
sw = File.AppendText(strFile)
sw.WriteLine("Start Error Log for today")
Catch ex As Exception
MsgBox("Error Creating Log File")
End Try
Else
sw = File.AppendText(strFile)
sw.WriteLine("Error Message in Occured at-- " & DateTime.Now)
sw.Close()
End If
Try this:
Dim strFile As String = "yourfile.txt"
Dim fileExists As Boolean = File.Exists(strFile)
Using sw As New StreamWriter(File.Open(strFile, FileMode.OpenOrCreate))
sw.WriteLine( _
IIf(fileExists, _
"Error Message in Occured at-- " & DateTime.Now, _
"Start Error Log for today"))
End Using
Don't check File.Exists() like that. In fact, the whole thing is over-complicated. This should do what you need:
Dim strFile As String = $#"C:\ErrorLog_{DateTime.Today:dd-MMM-yyyy}.txt"
File.AppendAllText(strFile, $"Error Message in Occured at-- {DateTime.Now}{Environment.NewLine}")
Got it all down to two lines of code :)
This should work for you without changing program logic (by not outputting "Start error" on the top of each file) like the other answers do :)
Remember to add exception handling code.
Dim filePath As String = String.Format("C:\ErrorLog_{0}.txt", DateTime.Today.ToString("dd-MMM-yyyy"))
Dim fileExists As Boolean = File.Exists(filePath)
Using writer As New StreamWriter(filePath, True)
If Not fileExists Then
writer.WriteLine("Start Error Log for today")
End If
writer.WriteLine("Error Message in Occured at-- " & DateTime.Now)
End Using
You didn't close the file after creating it, so when you write to it, it's in use by yourself. The Create method opens the file and returns a FileStream object. You either write to the file using the FileStream or close it before writing to it. I would suggest that you use the CreateText method instead in this case, as it returns a StreamWriter.
You also forgot to close the StreamWriter in the case where the file didn't exist, so it would most likely still be locked when you would try to write to it the next time. And you forgot to write the error message to the file if it didn't exist.
Dim strFile As String = "C:\ErrorLog_" & DateTime.Today.ToString("dd-MMM-yyyy") & ".txt"
Dim sw As StreamWriter
Try
If (Not File.Exists(strFile)) Then
sw = File.CreateText(strFile)
sw.WriteLine("Start Error Log for today")
Else
sw = File.AppendText(strFile)
End If
sw.WriteLine("Error Message in Occured at-- " & DateTime.Now)
sw.Close()
Catch ex As IOException
MsgBox("Error writing to log file.")
End Try
Note: When you catch exceptions, don't catch the base class Exception, catch only the ones that are releveant. In this case it would be the ones inheriting from IOException.
Why not just use the following simple call (with any exception handling added)?
File.AppendAllText(strFile, "Start Error Log for today")
EDITED ANSWER
This should answer the question fully!
If File.Exists(strFile)
File.AppendAllText(strFile, String.Format("Error Message in Occured at-- {0:dd-MMM-yyyy}{1}", Date.Today, Environment.NewLine))
Else
File.AppendAllText(strFile, "Start Error Log for today{0}Error Message in Occured at-- {1:dd-MMM-yyyy}{0}", Environment.NewLine, Date.Today)
End If
While I realize this is an older thread, I noticed the if block above is out of place with using:
Following is corrected:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filePath As String =
String.Format("C:\ErrorLog_{0}.txt", DateTime.Today.ToString("dd-MMM-yyyy"))
Using writer As New StreamWriter(filePath, True)
If File.Exists(filePath) Then
writer.WriteLine("Error Message in Occured at-- " & DateTime.Now)
Else
writer.WriteLine("Start Error Log for today")
End If
End Using
End Sub
Try it this way:
Dim filePath As String =
String.Format("C:\ErrorLog_{0}.txt", DateTime.Today.ToString("dd-MMM-yyyy"))
if File.Exists(filePath) then
Using writer As New StreamWriter(filePath, True)
writer.WriteLine("Error Message in Occured at-- " & DateTime.Now)
Else
writer.WriteLine("Start Error Log for today")
End Using
end if