Solved

File in use error - trying to delete a file I've recently created

Posted on 2012-03-26
7
275 Views
Last Modified: 2012-06-21
I'm writing a VB.NET 2010 application to take data from a text file, upload it to a SQL DB, then massage it prior to updating another database.

The data is coming from a UNIX system and I need to change the termination character to get Bulk Insert to work (don't ask me why, it's just the only way I've been able to get it to work).

I'm having a stupid problem with the clean up routine.

I use a streamreader to read the file and a streamwriter to write the changed data out to a temp file.  That's working fine.  Ultimately I then will delete the original file and rename the temp file.

Because I'm running it multiple times in testing I wanted to delete the temp file before I create a new one, but something in my code is holding a lock on it so that the routine gives a File in Use error and fails.

I can manually delete the file with no problems.  Then I run the code and it works, but if I run it a second time it fails.

Here's the code:
    Function ChangeTerminationChar(FI As FileInfo) As Boolean
        Dim fs As New FileStream(FI.FullName, FileMode.Open)

        Dim strFile As String = FI.DirectoryName & "\" & Left(FI.Name, Len(FI.Name) - 4) & ".tmp"
        If File.Exists(strFile) Then
            File.Delete(strFile)   'this line fails the second time I run the routine.
        End If

        Dim fsr As New StreamReader(fs)

        Using fstmp As New FileStream(strFile, FileMode.Create, FileAccess.ReadWrite)
            Using fsw As New StreamWriter(fstmp)
                Do Until fsr.Peek = -1
                    fsw.WriteLine(Replace(fsr.ReadLine(), Chr(10), Chr(13)))
                Loop
                fsw.Flush()
                fsw.Dispose()
            End Using
        End Using

        Return True
        Application.DoEvents()
        fsr.Close()
        fs.Close()
    End Function

Open in new window


Any ideas would be gratefully received as it's driving me crazy.
0
Comment
Question by:amt_sydney
  • 5
7 Comments
 
LVL 11

Assisted Solution

by:b_levitt
b_levitt earned 150 total points
ID: 37766629
It's been a while since I used VB over c#, but I believe it's because your fs.Close() is AFTER your "Return True".  In C# "return" terminates the method and returns to the caller, so any code after it is ignored and I believe that is also true with vb.net.
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 150 total points
ID: 37766942
b_levitt is right. VB works just like C# when you use Return. It gets you out of the function just as if you had an Exit Function instruction.
Put the Return after the Close, and you will solve the problem.

An alternative would be to use an alternative way of returning your value. You can simply assign the value to be returned to the name of the function:

ChangeTerminationChar = True

This also returns the value, but contrary to Return, the remaining code continues to execute. This a better choice in some situations were you have an intricate path inside of the method. If you have the choice however, as is the case here, use Return.

Another note about your code. Flush and Dispose are useless in what you are doing.

Flush is not necessary when you Close or Dispose of your stream. It is done automatically. You see it often in sample code because there was a bug with the streams in the first versions of .NET, and Flush was not called on closing. This is not necessary in 2010. The use of Flush is to make sure that the data is written to disk. It is typically used to make sure that the data is in the file and does not ends up lost in the memory buffer in case of an exception or a crash of the application. But it also slows down the writing.

As for the the Dispose, you have declared your variable with Using. The unique role of Using is to automatically call Dispose when you hit the End Using. So calling Dispose inside of a Using structure is useless.

Also, although it is generally a good habit to call Dispose on classes that implements it, you do not have to do it with streams. The documentation for Close is very clear : "This method calls Dispose, specifying true to release all resources."
0
 

Author Comment

by:amt_sydney
ID: 37769128
Damn, I was sure you were both correct, but changing that doesn't fix it.

The Flush and Dispose were there from before I implemented the Using construct, which I discovered was a better way of handling the stream from research into this problem.  I've taken them out and it makes no difference (of course).  

I've tried putting return at the end and I've tried assigning the value to the function, but have the same error.

One thing I've confirmed is that the file is being held open by something that is happening during the current run, not, as I previously thought, from the last run.
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 

Accepted Solution

by:
amt_sydney earned 0 total points
ID: 37769142
I fixed it.  Simple after a little sleep!

Stupid rookie mistake I'm afraid.  The FI variable was actually holding a reference to the file I was trying to delete.

Thanks for your suggestions though.  It's what let me look at it with fresh eyes.

Phil
0
 

Author Comment

by:amt_sydney
ID: 37769158
I've requested that this question be closed as follows:

Accepted answer: 0 points for amt_sydney's comment #37769142

for the following reason:

Because it works
0
 

Assisted Solution

by:amt_sydney
amt_sydney earned 0 total points
ID: 37769159
Sorry, I meant to split points between the contributors and pressed the wrong button.
0
 

Author Closing Comment

by:amt_sydney
ID: 37790465
It works
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question