Solved

c# - read text file then delete. Is there a better way than this?

Posted on 2013-07-01
5
593 Views
Last Modified: 2013-07-16
Hi,

I want to ReadAllLines from a text file, then delete the file. The file is created and written to by another application, so there is a chance of reading/deleting while the other application is trying to write.

This is what I have done. However Im sure there is a more professional way, any input appreciated.

private void ProcessFile(String fileName)
{
	string[] lines = File.ReadAllLines(fileName);

	while (true)
	{
		try
		{                
			System.IO.File.Exists(fileName);
			break;
		}
		catch (IOException)
		{
			Thread.Sleep(3000);
		} 
	} 
} 

Open in new window

0
Comment
Question by:mhdi
5 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 39292283
That doesn't delete a file.
System.IO.File.Exists(fileName);

it should be
System.IO.File.Delete(fileName);
0
 

Author Comment

by:mhdi
ID: 39292287
Whoops, that was a silly mistake. I will fix that.

What do you think about the overall logic? Is there a better way than the try/catch sleep idea?
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 166 total points
ID: 39292296
I suspect you intend this:

private void ProcessFile(String fileName)
{
      string[] lines = File.ReadAllLines(fileName);

      while (true)
      {
            try
            {                
                  if(System.IO.File.Exists(fileName))  System.IO.File.Delete(fileName);
                  break;
            }
            catch (IOException)
            {
                  Thread.Sleep(3000);
            }
      }
}

Otherwise it looks OK to attempt to delete and retry when fails.  
ps.  This must be in a separate thread else it will block the main thread of your app with the Sleep(3000) statement should the file not be deleted
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 167 total points
ID: 39292325
best practice would be to have the writing app notify that writing is over, so the reader can read and process the file and then delete it.
if its not feasible, you should use other method then using while(true) cause u may ended up in infinite loop if the file can't be deleted.
so what i'd do is having a background task which tries to delete the file every some interval for a duration of predefined time.
so for example if the file cannot be deleted after 5 minutes, something is wrong, the writer might still hold a handle to the file or something else.
exception handling is also a great measure, considering that entering a try/catch block is relatively fast , the overhead is negligible and you have the option to catch the specific exceptions, like IOException when the file is in use.
for .net 4.0 u can use this extension:
public static class FileExtensions
    {
        public static void DeleteAsync(this FileInfo fi, TimeSpan duration)
        {
            if (fi.Exists)
            {
                var now = DateTime.Now;
                while (DateTime.Now < now.Add(duration))
                {
                    try
                    {
                        Task.Factory.StartNew(() => fi.Delete());
                    }
                    catch (IOException)
                    {
                        //The specified file is in use or there is an open handle on the file, so suppress this exception
                        //all other exceptions will be thrown
                    }
                }
            }
        }
    }

Open in new window


all other .net versions:
public static class FileExtensions
    {
        public static void DeleteAsync(this FileInfo fi, TimeSpan duration)
        {
            if (fi.Exists)
            {
                var now = DateTime.Now;
                while (DateTime.Now < now.Add(duration))
                {
                    try
                    {
                                     ThreadPool.QueueUserWorkItem(delegate
            {
                fi.Delete();
            }, null);
                    }
                    catch (IOException)
                    {
                        //The specified file is in use or there is an open handle on the file, so suppress this exception
                        //all other exceptions will be thrown
                    }
                }
            }
        }
    }

Open in new window



to use this code:
new FileInfo(@"c:\temp\1.csv").DeleteAsync(new TimeSpan(0, 1, 0));

Open in new window

0
 
LVL 13

Assisted Solution

by:jonnidip
jonnidip earned 167 total points
ID: 39292694
Just a consideration.
If you want to READ the LATEST CONTENT of the file, I would rather try to "move" the file to another location/name and read it, while the other application writes a new file with the original name.

Just something like this:
String tempFileName = String.Empty;
File.Delete(tempFileName = Path.GetTempFileName());

while (true)
{
    try
    {
        File.Move(@"c:\temp\test.xml", tempFileName);
        break;
    }
    catch
    {
        System.Threading.Thread.Sleep(1000);
    }
}

String fileContent = File.ReadAllText(tempFileName);
File.Delete(tempFileName);

Open in new window

This will ensure you to have the latest content of the file, at the time it was moved.

Regards.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

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:…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

920 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