Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 750
  • Last Modified:

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

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
mhdi
Asked:
mhdi
3 Solutions
 
AndyAinscowCommented:
That doesn't delete a file.
System.IO.File.Exists(fileName);

it should be
System.IO.File.Delete(fileName);
0
 
mhdiAuthor Commented:
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
 
AndyAinscowCommented:
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
 
Meir RivkinFull stack Software EngineerCommented:
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
 
jonnidipCommented:
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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now