I have been writing an app in vb.net to copy the last few lines of an IIS W3C log file every few minusts to A file that will be used for some remote reporting.
Everything works when I test on my local PC but when I try it on the live IIS server it tells me the file is locked by another process, I take it IIS has it locked...
It does read in some of the sites log files (more than on site on the server) but not others, tells me locked/in use.
Why is it that I can always open the file in notepad but not open it in my app?
The Code:
Dim linex = ""
Dim Line = ""
'### IT ERROS OUT ON THE NEXT LINE ###
Using sr As New StreamReader("C:\inetpub\logs\LogFiles\W3SVC14\u_ex130702.log")
Do Until sr.EndOfStream
linex = sr.ReadLine()
line = line & linex & vbCrLf
Loop
End Using
You need to specify correct sharing options and open mode when creating underlying FileStream. Since there is no constructor of StreamReader that passes all necessary arguments you need to construct FileStream first using FileStream(String, FileMode, FileAccess, FileShare) and than create StreamReader on it using SrteamReader(Stream).
I think following should open IIS log file while it is being written to by IIS (if not - try other combinations of flags)
Using stream As New New FileStream( _
"Test####.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Using sr As New StreamReader(stream)
Related
I've developed a multi-user application. One user saves a string to a text file, other users have to read this string in a background process.
My problem is: when some users open the file to read the string, another user that wants to save a new string can't write to the file. I would like to implement a system that checks if the file is opened or not, and in case it is, waits a few seconds and retries.
What is the function or command to look if the file is already opened?
I solved my problem using tips:
i've replaced this code:
ip_acquisito = My.Computer.FileSystem.ReadAllText(path_elenco & "\ip.txt")
with this code:
Using fs As FileStream = File.Open(path_elenco & "\ip.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Dim b(1024) As Byte
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Do While fs.Read(b, 0, b.Length) > 0
ip_acquisito = temp.GetString(b)
Loop
End Using
There are quite a few patterns you can deal with. Two I'd recommend would be:
Dealing with FileAccess, FileMode and FileShare
Sync the file access with EventWaitHandle
I have attempted to find a way to download a file (from a PC running a Winform written in VB) from a web directory but could not get this done due to the date stamp that gets generated once the file is saved (filename must be precise). So now I'm trying the reverse (saving the file to the PC directly from the creation of the file).
Does anyone have any suggestions on methods to use (please no FTP due to proxy restrictions, same goes for client/server TCP/UDP). this will always be a .txt file.
thanks in advance.
If you can see the file contents by navigating to the URL, you can use an HttpWebRequest and a StreamReader / StreamWriter to save the data.
I'm downloading an example from http://textfiles.com/100/914bbs.txt
Dim request As HttpWebRequest
request = WebRequest.Create("http://textfiles.com/100/914bbs.txt")
request.Method = "GET"
Dim response = request.GetResponse
Using reader As New StreamReader(response.GetResponseStream)
Using writer As New StreamWriter("C:\myfilename.txt")
writer.Write(reader.ReadToEnd)
End Using
End Using
On close of an application written in VB, I need to copy the .sdf file, this is the local SQL Server CE database that syncs with the server. Each time we close the app we require a backup to be made.
I am using the file.copy method. First I close the connection to the database then copy the file to a specific location.
Dim conn As SqlCeConnection = New SqlCeConnection(My.Settings.MyClientConnectionString)
conn.Open()
conn.Close()
Dim tpath As String = My.Settings.CertPath
Dim path As String = tpath.Replace("db\", "MyDatabase.sdf")
Dim fs As FileStream = File.Create(path)
fs.Close()
File.Delete("C:\db\backup\MyDatabase.sdf")
File.Copy(path, "C:\db\backup\MyDatabase.sdf")
The problem arises on the line of code:
Dim fs As FileStream = File.Create(path)
The database becomes corrupted and has a size of 0 kb.
Has anyone seen this before? Thanks
Are you calling Create on an existing database file? According to the docs, Create creates or overwrites a file in the specified path. In the code you show, calling Create isn't necessary anyway. Just call File.Copy.
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.
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.