473,725 Members | 2,053 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

StreamWriter and/or System.IO.File problems

Don
I'm having problems working with a streamwriter object. After closing the
streamwriter and setting it to Nothing, I try to delete the file it was
writing to, but I always get the following error message:

"The process cannot access the file "whatever" because it is being used
by another process."

I've even tried opening another file using the same streamwriter object
before deleting the original file, but it's no use. Something keeps a lock
on that original file, but I can't figure out what.

To reproduce this bug, create a new Windows Application project and create
the following class:
--- START ---
Imports System.IO

Public Class StreamWriterTes t

#Region " Constructor/Destructor "

Public Sub New(ByVal filename As String)

' Remember the filename
_filename = filename

' Determine the path we should be storing the log file in
_folder =
System.Environm ent.ExpandEnvir onmentVariables ("%WinDir%") & "\Temp\"

' Open the log file
OpenLogFile()

End Sub

Protected Overrides Sub Finalize()

' Close the log file
CloseLogFile()

MyBase.Finalize ()

End Sub

#End Region
#Region " Variables "

Private _filename As String = String.Empty ' log file name
Private _folder As String = String.Empty ' folder the log file is
in (always has a trailing \)
Private _logWriter As StreamWriter ' used to write to the
log file

#End Region
#Region " Properties "

Public ReadOnly Property Path() As String
Get
Return _folder & _filename
End Get
End Property
Public ReadOnly Property NewPath() As String
Get
Return _folder & _filename & "_"
End Get
End Property

#End Region
#Region " Methods "

Private Sub OpenLogFile()
Dim sqlLogFileSize As Long = 0
Try

' for debugging purposes
Console.WriteLi ne("*** Log File Opened : " & Me.Path)

' Create a new streamwriter object
_logWriter = New StreamWriter(Me .Path)

' Make the streamwriter automatically flush changes to the
file to the
' harddisk everytime we use the Write method
_logWriter.Auto Flush = True

' Write a header to the file
_logWriter.Writ eLine("test")

Catch ex As Exception

Console.WriteLi ne("***ERROR : " & ex.Message)

End Try
End Sub
Private Sub CloseLogFile()
' DD Jul 23/04
'
' Closes the log file
Try

_logWriter.Clos e()
_logWriter = Nothing
GC.Collect()
Console.WriteLi ne("*** Log File Closed : " & Me.Path)

Try

If IO.File.Exists( Me.NewPath) Then
IO.File.Delete( Me.NewPath)

If Not IO.File.Exists( Me.NewPath) Then
'IO.File.Move(M e.Path, Me.NewPath)
IO.File.Copy(Me .Path, Me.NewPath)
IO.File.Delete( Me.Path)
Console.WriteLi ne("*** Log File Renamed : " &
Me.NewPath)
Else
Console.WriteLi ne("*** Log File NOT Renamed.
Another file with the same name already exists and could not be deleted.")
End If

Catch ex As Exception

Console.WriteLi ne("Error: Log File NOT Renamed: {0}",
ex.Message)

End Try

Catch ex As Exception

Console.WriteLi ne("Error closing log file: {0}", ex.Message)

End Try
End Sub

#End Region

End Class
--- END ---
Now place a button on Form1 and put the following code in it:
--- START ---

Randomize()

Dim x As StreamWriterTes t
x = New StreamWriterTes t("test1" & Format(Int(Rnd( ) * 99999999),
"00000000") )
x = Nothing
GC.Collect()

--- END ---
Looking at the Output Window, you'll see that the IO.File.Delete( ) raises
the exception. I am at my wits end trying to figure this out.

BTW, I don't think the bug occurs if you try to do the whole thing in, say,
the button's click event. It seems the fact that this code is the Finalize
method of a class has something to do with it.

- Don
Nov 21 '05 #1
6 10215
you are setting the varibale to nothing before the call to the
finalizer. additionally, you shouldn't do explicit GC unless
absolutely necessary.

this works fine...
Imports System.IO
Module Module1
Public Class StreamWriterTes t

Public Sub New(ByVal filename As String)

' Remember the filename
_filename = filename

' Determine the path we should be storing the log file in
_folder = System.Environm ent.ExpandEnvir onmentVariables ("%WinDir%")
& "\Temp\"

' Open the log file
OpenLogFile()

End Sub

Protected Overrides Sub Finalize()

' Close the log file
CloseLogFile()

MyBase.Finalize ()

End Sub

Private _filename As String = String.Empty ' log file name
Private _folder As String = String.Empty ' folder the log file is
in (always has a trailing \)
Private _logWriter As StreamWriter ' used to write to the log
file

Public ReadOnly Property Path() As String
Get
Return _folder & _filename
End Get
End Property
Public ReadOnly Property NewPath() As String
Get
Return _folder & _filename & "_"
End Get
End Property

Private Sub OpenLogFile()
Try
Debug.WriteLine ("*** Log File Opened : " & Me.Path)
_logWriter = New StreamWriter(Me .Path)
_logWriter.Auto Flush = True
_logWriter.Writ eLine("test")
Catch ex As Exception
Debug.WriteLine ("***ERROR : " & ex.Message)
End Try

End Sub
Private Sub CloseLogFile()

Try
_logWriter.Clos e()
Debug.WriteLine ("*** Log File Closed : " & Me.Path)
If IO.File.Exists( Me.NewPath) Then IO.File.Delete( Me.NewPath)
Catch ex As Exception
Debug.WriteLine ("Error closing log file: {0}", ex.Message)
End Try
End Sub

End Class

Sub main()
Randomize()
Dim x As StreamWriterTes t
x = New StreamWriterTes t("test1" & Format(Int(Rnd( ) * 99999999),
"00000000") )
End Sub

End Module

Nov 21 '05 #2
Don
> you are setting the varibale to nothing before the call to the
finalizer.
I don't see what the problem with this is. Setting it to Nothing should
make its Finalize method get called when garbage collection time comes
around. I've never had problems with this.

additionally, you shouldn't do explicit GC unless
absolutely necessary.
That was just to highlight the bug. Taking that line out makes the bug
occur when you shut the program down. It behaves exactly the same way in
either case.

this works fine...


This only works because you removed these lines of code from
StreamWriterTes t.CloseLogFile:

If Not IO.File.Exists( Me.NewPath) Then
IO.File.Copy(Me .Path, Me.NewPath)
IO.File.Delete( Me.Path)
Console.WriteLi ne("*** Log File Renamed : " & Me.NewPath)
Else
Console.WriteLi ne("*** Log File NOT Renamed. Another file with the
same name " & _
"already exists and could not be deleted.")
End If

If I comment those lines in my original class and leave the rest of the code
intact, it works, too. That's because the file created by the StreamWriter
is never touched after the StreamWriter is closed. If you'll notice in the
code you posted, the file being written to by the StreamWriter is not the
file that is deleted in CloseLogFile(). Me.NewPath gets deleted, not
Me.Path, which is the file we just created with the StreamWriter.

It seems that, after closing the StreamWriter, the file remains locked until
the application itself shuts down...and this happens only if the
StreamWriter is in another class and when it is closed in that class's
Finalize event.

- Don

Nov 21 '05 #3

"Don" <un*****@oblivi on.com> wrote in message
news:aIGpe.1602 505$8l.1591155@ pd7tw1no...
:
: I'm having problems working with a streamwriter object. After closing
: the streamwriter and setting it to Nothing, I try to delete the file
: it was writing to, but I always get the following error message:
:
: "The process cannot access the file "whatever" because it is being
: used by another process."
:
: I've even tried opening another file using the same streamwriter
: object before deleting the original file, but it's no use. Something
: keeps a lock on that original file, but I can't figure out what.
:
: To reproduce this bug, create a new Windows Application project and
: create : the following class:
<snip original code sample>
: Looking at the Output Window, you'll see that the IO.File.Delete( )
: raises the exception. I am at my wits end trying to figure this out.
:
: BTW, I don't think the bug occurs if you try to do the whole thing in,
: say, the button's click event. It seems the fact that this code is
: the Finalize method of a class has something to do with it.
:
: - Don
I can't reproduce this. I copied your code into a console app with a few
changes. I removed your original comments and added new comments to flag
my changes (highlighted below). I only made two changes of any note:
* I added a new function 'ZapThisPuppyNo w' to the class so I could
force a finalize event.

* And I added a test to the close log file function to ensure the
_logWriter object exists before I try to access it.

Apart from that, the core of your code is unchanged.

------------------------------------------
'[ADDED IMPORTS]
Imports Microsoft.Visua lBasic
Imports System
Imports System.IO

'[ADDED SUB MAIN (REPLACES BUTTON EVENT CODE)]
public Class [class]
Public Shared Sub Main
Console.WriteLi ne("Enter Main" & vbCrLf)

Console.WriteLi ne("Creating Object" & vbCrLf)
Dim swt As New StreamWriterTes t("swt.test")

Console.WriteLi ne("Finalizing Object" & vbCrLf)
swt.ZapThisPupp yNow

Console.WriteLi ne("Releasing Object" & vbCrLf)
swt = Nothing

Console.WriteLi ne("Exit Main" & vbCrLf)
End Sub
End Class
Public Class StreamWriterTes t

'[ADD FUNCTION TO EXPLICITLY CALL FINALIZE]
Public Sub ZapThisPuppyNow ()
Finalize
End Sub

'[ADD CONSOLE OUTPUT]
Public Sub New(ByVal filename As String)
Console.WriteLi ne("Constructin g Class - " & filename & vbCrLf)

_filename = filename
_folder = "I:\tmp\"
Console.WriteLi ne("_filename = " & _filename & vbCrLf)
Console.WriteLi ne("_folder = " & _folder & vbCrLf)

OpenLogFile()
Console.WriteLi ne("End Constructing Class" & vbCrLf)
End Sub

'[ADD CONSOLE OUTPUT]
Protected Overrides Sub Finalize()
Console.WriteLi ne("Finalizing Class" & vbCrLf)
CloseLogFile()

Console.WriteLi ne("Finalizing MyBass Class" & vbCrLf)
MyBase.Finalize ()

Console.WriteLi ne("End Finalizing Class" & vbCrLf)
End Sub

Private _filename As String = String.Empty
Private _folder As String = String.Empty
Private _logWriter As StreamWriter

Public ReadOnly Property Path() As String
Get
Return _folder & _filename
End Get
End Property
Public ReadOnly Property NewPath() As String
Get
Return _folder & _filename & "_"
End Get
End Property

'[ADD CONSOLE OUTPUT]
Private Sub OpenLogFile()
Console.WriteLi ne("Enter 'OpenLogFile'" & vbCrLf)

Dim sqlLogFileSize As Long = 0
Try
Console.WriteLi ne("*** Log File Opened : " & Me.Path)
_logWriter = New StreamWriter(Me .Path)
_logWriter.Auto Flush = True
_logWriter.Writ eLine("test")
Catch ex As Exception
Console.WriteLi ne("***ERROR : " & ex.Message)
End Try

Console.WriteLi ne("Exit 'OpenLogFile'" & vbCrLf)
End Sub

'[ADD CONSOLE OUTPUT]
Private Sub CloseLogFile()
Console.WriteLi ne("Enter 'CloseLogFile'" & vbCrLf)

Try

'[ADDED TEST]
If _logWriter Is Nothing Then
Console.WriteLi ne("_logWriter Already Released")
Console.WriteLi ne("Exiting Sub" & vbCrLf)
Goto Exit_sub
End If

_logWriter.Clos e()
_logWriter = Nothing
GC.Collect()
Console.WriteLi ne("*** Log File Closed : " & Me.Path)

Try

'[CHANGE TO BLOCK IF/END IF]
If IO.File.Exists( Me.NewPath) Then
IO.File.Delete( Me.NewPath)
End If

If Not IO.File.Exists( Me.NewPath) Then
IO.File.Copy(Me .Path, Me.NewPath)
IO.File.Delete( Me.Path)
Console.WriteLi ne("*** Log File Renamed : " & Me.NewPath)
Else
Console.WriteLi ne("*** Log File NOT Renamed. Another " & _
"file with the same name already " & _
"exists and could not be deleted.")
End If
Catch ex As Exception
Console.WriteLi ne("Error: Log File NOT Renamed: {0}", _
ex.Message)
End Try
Catch ex As Exception
Console.WriteLi ne("Error closing log file: {0}", ex.Message)
End Try

'[ADDED LABEL IN ORDER TO CAPTURE EXIT EVENT]
Exit_Sub:
Console.WriteLi ne("Exit 'CloseLogFile'" & vbCrLf)
End Sub
End Class
------------------------------------------

I compiled as "vbc /out:test.exe test.vb"
When I ran 'Test.exe' from the command line as written above, I received
the following output:

=============== =============== =============
I:\tmp>test
Enter Main

Creating Object

Constructing Class - swt.test

_filename = swt.test

_folder = I:\tmp\

Enter 'OpenLogFile'

*** Log File Opened : I:\tmp\swt.test
Exit 'OpenLogFile'

End Constructing Class

Finalizing Object

Finalizing Class

Enter 'CloseLogFile'

*** Log File Closed : I:\tmp\swt.test
*** Log File Renamed : I:\tmp\swt.test _
Exit 'CloseLogFile'

Finalizing MyBass Class

End Finalizing Class

Releasing Object

Exit Main

Finalizing Class

Enter 'CloseLogFile'

_logWriter Already Released
Exiting Sub

Exit 'CloseLogFile'

Finalizing MyBass Class

End Finalizing Class
=============== =============== =============
Note that finalize is called twice - once manually by calling function
ZapThisPuppyNow and again when the 'Main' sub exits.
Here is the output when I run the code with the call to function
'ZapThisPuppyNo w' commented out:

=============== =============== =============
Enter Main

Creating Object

Constructing Class - swt.test

_filename = swt.test

_folder = I:\tmp\

Enter 'OpenLogFile'

*** Log File Opened : I:\tmp\swt.test
Exit 'OpenLogFile'

End Constructing Class

Releasing Object

Exit Main

Finalizing Class

Enter 'CloseLogFile'

*** Log File Closed : I:\tmp\swt.test
*** Log File Renamed : I:\tmp\swt.test _
Exit 'CloseLogFile'

Finalizing MyBass Class

End Finalizing Class
=============== =============== =============
Ralf
Nov 21 '05 #4
didn't catch your nuance in the original code, but this works without a
hitch

Private Sub CloseLogFile()

Try
_logWriter.Clos e()
Debug.WriteLine ("*** Log File Closed : " & Me.Path)
If IO.File.Exists( Me.NewPath) Then IO.File.Delete( Me.NewPath)
If IO.File.Exists( Me.Path) Then IO.File.Delete( Me.Path)
Catch ex As Exception
Debug.WriteLine ("Error closing log file: {0}", ex.Message)
End Try
End Sub

there was an issue specifically with the x=Nothing line when I tested
it the first time (a Null reference exception). I was NOT able to
replicate your specific error, but in hindsight suspect that you had it
open in a viewer to check its contents when the deletion was requested.

as for your original code, I have a great number of issues which I will
summarize as "Don't do it this way!"
1) Close the file as soon as you are done with it! If you need back
into it, re-open it.
2) Use Try...Catch...F inally.
3) Test to make sure that the file actualy opened, before closing it.
4) Combine _folder and _filename into one member variable and access it
directly
5) Don't use property calls within the class; you already own the
private member fields
6) If the output is for debug, use the Debug class and not the console

Nov 21 '05 #5
Don
"_AnonCowar d" <ab*@xyz.com> wrote in message
news:Ws******** *********@twist er.southeast.rr .com...

"Don" <un*****@oblivi on.com> wrote in message
news:aIGpe.1602 505$8l.1591155@ pd7tw1no...

I can't reproduce this.
My original code worked fine on your computer? That's odd....

I copied your code into a console app with a few
changes. I removed your original comments and added new comments to flag
my changes (highlighted below). I only made two changes of any note:

* I added a new function 'ZapThisPuppyNo w' to the class so I could
force a finalize event.


Yes, I know that explicitly calling a method to close the file before
destroying the object will make everything work fine. Unfortunately it
defeats the purpose of what I wanted to do: have the opening and closing of
the file be automatic without having to make any special method calls to
either open or close the file. Unfortunately, it looks like there's not
other way around this bug. :(

- Don
Nov 21 '05 #6
Don
Thanks for the tips, but it looks like this is a lost cause. I guess I'll
just have to go to Plan B where I have to manually call methods to open and
close the log file. Too bad.

- Don
Nov 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2460
by: Majed | last post by:
Hi , all I'm trying to write unicode to a file for another app (not developed with vs2003) to read it. I used StreamWriter with unicode encoding.but I was surprised that the streamwriter adds FFFE to the start of the file,which stopes the other app from reading it!! any idea how to stope it frome doing that,do I have to use another class #####writer that supports unicode? help me Please! Thanks
0
1515
by: notalent | last post by:
I'm having a problem with a very basic program. I'm creating a app in Visual Studio (2003) C# to zip up a collection of specified files & directories and save them to a certain location. I have a checkedListBox that holds all the directories and files that I want saved. I have two buttons (One for selecting file & one for directory) that are hooked to a openFileDialog and folderBrowserDialog. When a new file or dir is selected, it...
1
7601
by: Lars Hansen | last post by:
Hi This is probably pretty basic, but I have a problem with the access-level (local variable), when creating a new StreamWriter. I am trying to write some price information to a textfile - which works fine. But due to the dataamounts involved I now need to split it out to several files. The actions I am taking are: - create the first file
5
18888
by: Brendan Miller | last post by:
Hi, I have been having a problem writing the contents of a dataset to a .csv file. When I write to a .csv file and open it with either Excel or Wordpad the "french" characters are wrong. When I open the file with notepad the characters are displayed correctly. e.g. in notepad: École, in Wordpad/Excel: Ã?cole. Having the user import a text file and format it themselves is not an option. The output must be .csv. The function I was...
4
20562
by: rex64 | last post by:
I am getting an error message and I have not been able to figure hot how to fix it. I have done some research with no answers yet. I found this code that may help? Not sure what to do with it. using (StreamWriter sw = new StreamWriter (fullAddress , false, Encoding.UTF7)) Error message::::::::::::::::::::::::::::::::::::::::::::::
10
4656
by: Oscar Thornell | last post by:
Hi, I generate and temporary saves a text file to disk. Later I upload this file to Microsoft MapPoint (not so important). The file needs to be in UTF-8 encoding and I explicitly use the "Encoding.UTF8" in the constructor like this: StreamWriter writer = new StreamWriter(file, Encoding.UTF8); When I do this the StreamWriter inserts an UTF-8 preamble "" into the
3
3721
by: Don | last post by:
I have a strange bug popping up every once in a while. I've got a section of code that executes these statements when working with a streamwriter: --- Start --- .... ' Close the streamwriter _fileWriter.Close()
2
2074
by: David Buchan | last post by:
I have written a program to write some text to a file. Currently, if the file already exists, the program simply overwrites it. What I'd like to do, is have the program ask me if I wish to overwrite the existing file, ask for a new name if the answer is no, or overwrite if the answer is yes. I have the line: Dim objWriter As StreamWriter = New StreamWriter(OutputFileName)
3
3913
by: philip | last post by:
If I execute that : Dim Temp as string = "This is a text" Dim sw As StreamWriter Dim fullFileName as string = "c:\text.txt" sw = New StreamWriter(fullFilename) sw.Write(temp) sw.Close() the resulting file 'Text.txt' has the same length than the string 'temp'.
0
8752
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9401
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9257
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9174
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8096
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6702
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4517
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2634
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2157
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.