Visual basic write in an opened file (printLine) - vb.net

So I want to do this:
Open file "this.txt"
Write a line to this file (replacing anything else written to this file)
[Other stuff, irrelevant to the file]
Write a line to this file (replacing anything else written to this file)
Close the file
I thought it would be easy, but I was wrong. I tried many ways, but they all failed. Either they wouldn't let me write in an open file, or they would open the file and immediately close it (WriteAllText).
I ended up using FileOpen(), PrintLine() and FileClose() which lets me write in an open file but PrintLine only writes a new line, it doesn't replace everything in the file. Any help? Either with the printline or the whole thing
It is crucial that the file stays open until the very last moment I want it closed, (cause I have another program checking to see when this file is not open/used).

If this is about VB.NET, then you can use File.Open() with mode = FileMode.Truncate. This clears the file on opening. This assumes that the file exists.
You can also use SetLength() to truncate:
Dim f As FileStream
' FileMode.Truncate also works, but the file needs to exist from before
f = File.Open("test.txt", FileMode.OpenOrCreate, FileAccess.Write)
f.SetLength(0) ' truncate to zero size
Dim line As String = "hello2"
Dim w = New StreamWriter(f)
w.WriteLine(line)
w.Flush()
w.Close()
f.Close()
If this is about VB6, check out this question. One solution there is to import and use a native Windows function that does truncation.

In VB.Net OpenTextFileWriter does exactly what you need (docs):
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("c:\test.txt", False)
file.WriteLine("Here is the first string.")
file.Close()

Related

Using the same file error

On a button click I have the following code to write what Is in my textboxes.
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("C:/Users/Nick/Documents/Dra.txt", False)
file.WriteLine(NameBasic)
file.WriteLine(LastBasic)
file.WriteLine(PhoneBasic)
file.WriteLine(NameEmer1)
On my form load, I load what is in the notepad from what was written, It is saying It is already being used(the file) which is true, how can I have two different functions(write, and read) manipulating the same file with out this error?
The process cannot access the file 'C:\Users\Nick\Documents\Dra.txt' because it is being used by another process.
And here is the code for my onformload
Dim read As System.IO.StreamReader
read = My.Computer.FileSystem.OpenTextFileReader("C:/Users/Nick/Documents/Dra.txt")
lblNameBasic.Text = read.ReadLine
I am sort of stuck on this problem, thank you
You need to close the file when you are done writing to it.
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("C:/Users/Nick/Documents/Dra.txt", False)
file.WriteLine(NameBasic)
file.WriteLine(LastBasic)
file.WriteLine(PhoneBasic)
file.WriteLine(NameEmer1)
file.Close()
To answer your question:
how can I have two different functions(write, and read) manipulating the same file with out this error?
If you really want to simultaneously read and write to the same file from two processes, you need to open the file with the FileShare.ReadWrite option. The My.Computer.FileSystem methods don't do that.¹
However, I suspect that you don't really wan't to do that. I suspect that you want to write and, after you are finished writing, you want to read. In that case, just closing the file after using it will suffice. The easiest way to do that is to use the Using statement:
Using file = My.Computer.FileSystem.OpenTextFileWriter(...)
file.WriteLine(...)
file.WriteLine(...)
...
End Using
This ensures that the file will be closed properly as soon as the Using block is left (either by normal execution or by an exception). In fact, it is good practice to wrap use of every object whose class implements IDisposable (such as StreamWriter) in a Using statement.
¹ According to the reference source, OpenTextFileWriter creates a New IO.StreamWriter(file, append, encoding), which in turn creates a new FileStream(..., FileShare.Read, ...).

Write to a text file while is it open and visible

I'm sure this is really simple, but has had me stumped for a while!
I need to show the user a text file, with lines being written to it as my program executes. Stuff like "Working on this file - Successful!". Another forum thread has helped me to allow the text file to be accessed by multiple processes, but now when I open the text file using Process.Start, it doesn't show the lines that are being written using the StreamWriter. Any help very much appreciated.
Code:
Dim ExportLog As String = "C:\ExportLog.txt"
If System.IO.File.Exists(ExportLog) Then
System.IO.File.Delete(ExportLog)
End If
Using writeStream = System.IO.File.Open(ExportLog,
FileMode.OpenOrCreate, FileAccess.ReadWrite,
FileShare.ReadWrite), Write As New StreamWriter(writeStream)
Write.WriteLine("Starting")
End Using
Dim MyLog As Process = Process.Start(ExportLog)

Program not able to write to a newly made text file

After some great arguments made by other users in this question: How to write to a text file inside of the application, I decided to not use a resource file, instead create a file in a folder & then read/write from there.
Although, for some reason, I can't seem to write to the file in question, it keeps throwing an exception telling me the file is already in use by another process.
Here's the code which I use for writing to this file.
If System.IO.File.Exists(credentials) Then
Dim objWriter As New System.IO.StreamWriter(credentials, False)
objWriter.WriteLine(remember)
objWriter.Close()
Else
System.IO.Directory.CreateDirectory(Mid(My.Application.Info.DirectoryPath, 1, 1) & ":\ProgramData\DayZAdminPanel")
System.IO.File.Create(credentials)
Dim objWriter As New System.IO.StreamWriter(credentials, False)
objWriter.WriteLine(remember)
objWriter.Close()
End If
Any ideas on how I can write to the text file in question?
There's a good chance that a previous iteration of your application failed to properly close access to the file in the StreamWriter. Since your constructor is set to overwrite (and not append) to the file, this could be the source.
Try setting up your application with a "Using" statement to properly open/close the file:
If System.IO.File.Exists(credentials) Then
Using objWriter As StreamWriter = New StreamWriter(credentials, False)
objWriter.WriteLine(remember)
objWriter.Close()
End Using
Else
System.IO.Directory.CreateDirectory(Mid(My.Application.Info.DirectoryPath, 1, 1) & ":\ProgramData\DayZAdminPanel")
System.IO.File.Create(credentials)
Using objWriter As StreamWriter = New StreamWriter(credentials, False)
objWriter.WriteLine(remember)
objWriter.Close()
End Using
End If
It does look rather redundant to have a Using block and a close statement, but this ensures access to your file even if an exception occurs.
You are trying to create a directory in the common application data directory. This directory should be found using the Environment class methods and enums because is different between operating systems. However you use the value credentials for the filename. I suppose that you want to store your datafile in the common application directory and not in a place where there is no permission to write data files (Like C:\program files (x86)).
Then, to avoid problems with file stream not correctly closed try to use the Using statement that assures a correct closure and disposal of your file resource (No need to call close inside a Using).
Also, notice that StreamWriter is perfectly capable to create the file if it doesn't exists or if you wish to overwrite the previous contents (passing false for the Append flag).
So your code could be reduced to these lines.
' Get the common application data directory (could be different from Win7 and XP)
Dim workDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
' Combine with your own working data directory
workDir = Path.Combine(workdir, "DayZAdminPanel")
' Create if not exists
If Not Directory.Exists(workDir) Then
Directory.CreateDirectory(workDir)
End If
' Create/Overwrite your data file in a subfolder of the common application data folder
Dim saveFile = Path.Combine(workDir, Path.GetFileName(credentials))
Using objWriter = New System.IO.StreamWriter(saveFile, False)
objWriter.WriteLine(remember)
End Using
File.Create returns an opened FileStream that you should be passing into the StreamWriter constructor on the subsequent, rather than passing the filename again, or you can just omit the File.Create call altogether.
You might want to look into a Using block for the StreamWriter so it gets predictably closed.

Loading Sequential Files in VB

I have written a vb program a few years ago and now as I get started with vb again i am hitting a "snag". With sequential files. I am trying to load a file in to the vb program with the file dialog box.
NOTE:I am using structures
Dim FileDialog as new openFileDialog
Dim MyStream as Stream = nothing
Dim FileLocation as string 'this is to save the file location
if( FileDialog.ShowDialog() = DialogResults.OK)Then
FS = new FileStream(FileLocation, FileMode.open, fileaccess.Read)
BF = new BinaryFromatter
While FS.Position < FS.Length
Dim temp as unit
...'Please note that this is where the file reads the structures data.It is to much code to write in.
When I run the program I can create a file and save it with the data in and I can load it with the Dialog box, The problem is when I run the program again and try to load it. It just wont run the file or load it(Remember I created the file with this program and saved)
How do I get this to work?
Make sure you have closed the file after writing and reading the data the first time, and make sure you are using the correct path (FileLocation).
Exit Visual Studio between the first and second times you run the program. If it works then, then you know you are not closing the file properly.
Set a breakpoint at the new FileStream assignment and check the value of FileLocation. Is it the same as it was when the file was written?
Check the error message, if there is one, and see if that tells you anything.

VB.Net File.Exists() Returns True but Excel cannot Open

I check for the existence of the file with File.Exists(filePath). Then I try to open the file from within Excel with Excel.Workbooks.OpenText(filePath). But Excel complains that the file's not there. What the heck?
The context is that I am shelling out to another application to process a given file and produce a .out file, which I then convert to an Excel workbook.
'' At this point, filePath is a .txt file.
Dim args As String = String.Format("""{0}""", filePath)
...
Dim exe As String = Config.ExtractEXE
Dim i As New ProcessStartInfo(exe)
i.Arguments = args
Dim p As Process = Process.Start(i)
p.WaitForExit()
...
'' filePath now becomes the .out file.
'' Then eventually, I get around to checking:
'If Not File.Exists(filePath) Then
' MsgBox("Please ensure...")
' Exit Sub
'End If
'' In response to an answer, I no longer check for the existence of the file, but
'' instead try to open the file.
Private Function fileIsReady(filePath As String) As Boolean
Try
Using fs As FileStream = File.OpenRead(filePath)
Return True
End Using
Catch
Return False
End Try
End Function
Do Until fileIsReady(filePath)
'' Wait.
Loop
ExcelFile.Convert(filePath...)
'' Wherein I make the call to:
Excel.Workbooks.OpenText(filePath...)
'' Which fails because filePath can't be found.
Is there a latency issue, such that .Net recognizes the existence of the file before it's accessible to other applications? I just don't understand why File.Exists() can tell me the file is there and then Excel can't find it.
As far as I know, the only application that might have the file open is the application I call to do the processing. But that application should be finished with the file by the time p.WaitForExit() finishes, right?
I've had to deploy the application with this as a known bug, which really sucks. There's an easy workaround for the user; but still--this bug should not be. Hope you can help.
Whether or not a file exists is not the only factor in whether you can open it. You also need to look at file system permissions and locking.
File.Exists can lie to you (it returns false if you pass a directory path or if any error occurs, even if the file does exist)
The file system is volatile, and things can change even in the brief period between an if (File.Exists(...)) line and trying to open the file in the next line.
In summary: you should hardly ever use file.exists(). Almost any time you are tempted to do so, just try to open the file and make sure you have a good exception handler instead.