Hassen
Hassen

Reputation: 870

wait for a TXT file to be readable c#

My application use "FileSystemWatcher()" to raise an event when a TXT file is created by an "X" application and then read its content.

the "X" application create a file (my application detect it successfully) but it take some time to fill the data on it, so the this txt file cannot be read at the creation time, so im

looking for something to wait until the txt file come available to reading. not a static delay but something related to that file.

any help ? thx

Upvotes: 3

Views: 5656

Answers (9)

ryber
ryber

Reputation: 4555

If you have a DB at your disposal I would recommend using a DB table as a queue with the file names and then monitor that instead. nice and transactional.

Upvotes: 0

Steven Evers
Steven Evers

Reputation: 17196

We have a virtual printer for creating pdf documents, and I do something like this to access that document after it's sent to the printer:

using (FileSystemWatcher watcher = new FileSystemWatcher(folder))
{
    if(!File.Exists(docname))
        for (int i = 0; i < 3; i++)
            watcher.WaitForChanged(WatcherChangeTypes.Created, i * 1000);
}

So I wait for a total of 6 seconds (some documents can take a while to print but most come very fast, hence the increasing wait time) before deciding that something has gone awry.

After this, I also read in a for loop, in just the same way that I wait for it to be created. I do this just in case the document has been created, but not released by the printer yet, which happens nearly every time.

Upvotes: 1

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

You can open and read a locked file like this

using (var stream = new FileStream(@"c:\temp\file.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
   using (var file = new StreamReader(stream)) {
      while (!file.EndOfStream) {
         var line = file.ReadLine();
         Console.WriteLine(line);
      }
   }
}

However, make sure your file writer flushes otherwise you may not see any changes.

Upvotes: 1

Ronald Wildenberg
Ronald Wildenberg

Reputation: 32094

The application X should lock the file until it closes it. Is application X also a .NET application and can you modify it? In that case you can simply use the FileInfo class with the proper value for FileShare (in this case FileShare.Read).

If you have no control over application X, the situation becomes a little more complex. But then you can always attempt to open the file exclusively via the same FileInfo.Open method. Provide FileShare.None in that case. It will attempt to open the file exclusively and will fail if the file is still in use. You can perform this action inside a loop until the file is closed by application X and ready to be read.

Upvotes: 1

RaYell
RaYell

Reputation: 70414

You can use the same class to be notified when file changes.

The Changed event is raised when changes are made to the size, system attributes, last write time, last access time, or security permissions of a file or directory in the directory being monitored.

So I think you can use that event to check if file is readable and open it if it is.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564343

You could track the file's Changed event, and see if it's available for opening on change. If the file is still locked, just watch for the next change event.

Upvotes: 2

Mike Blandford
Mike Blandford

Reputation: 4012

Create the file like this:

myfile.tmp

Then when it's finished, rename it to

myfile.txt

and have your filewatcher watch for the .txt extension

Upvotes: 4

David
David

Reputation: 73554

The only way I have found to do this is to put the attempt to read the file in a loop, and exit the loop when I don't get an exception. Hopefully someone else will come up with a better way...

bool FileRead = false;

while (!FileRead)
{
   try
   {

      // code to read file, which you already know
      FileRead = true;
   }
   catch(Exception)
   {
      // do nothing or optionally cause the code to sleep for a second or two

   }


}

Upvotes: 3

Marcin Deptuła
Marcin Deptuła

Reputation: 11957

You can check if file's size has changed. Although this will require you to poll it's value with some frequency.
Also, if you want to get the data faster, you can .Flush() while writing, and make sure to .Close() stream as soon as you will finish writing to it.

Upvotes: -1

Related Questions