Solved

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

Posted on 2012-03-26
7
268 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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
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…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

743 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now