Solved

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

Posted on 2012-03-26
7
270 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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
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…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

896 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

12 Experts available now in Live!

Get 1:1 Help Now