Solved

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

Posted on 2012-03-26
7
284 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 to Create Failover DNS Record Sets in Route 53

Route 53 has the ability to easily configure DNS record sets specifically for failover scenarios. These failover record sets can be configured to failover to full-blown deployments in other regions or to a static HTML page that informs your customers of the issue.

 

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

Veeam gives away 10 full conference passes

Veeam is a VMworld 2017 US & Europe Platinum Sponsor. Enter the raffle to get the full conference pass. Pass includes the admission to all general and breakout sessions, VMware Hands-On Labs, Solutions Exchange, exclusive giveaways and the great VMworld Customer Appreciation Part

Question has a verified solution.

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

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)…
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
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…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…

630 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