user2908206
user2908206

Reputation: 265

c#: best way to ensure my file closed

So i have this function that checks if my File is still in use (in order to wait before try to copy and delete it):

    private static bool IsFileLocked(FileInfo file)
    {
        FileStream stream = null;

        try
        {
            using (stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None))
            {

            }
        }
        catch (IOException)
        {
            // The file is unavailable because it is:
            // 1. Still being written to.
            // 2. Being processed by another thread.
            // 3. Does not exist (has already been processed).

            if (stream != null)
                stream.Close();
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }

        //file is not locked
        return false;
    }

So this is enough to call Close() method or maybe use using to ensure the file Closed after finish my method ?

Upvotes: 1

Views: 629

Answers (2)

InBetween
InBetween

Reputation: 32750

The other answers and comments already point out the redundancies in your code and why your current approach might not to work out too well. I'll try to give you some guidelines on how to solve the more general problem.

The approach I'd use is the following:

  1. Create a concurrent queue that keeps track of files pending copy. Update this queue conveniently adding files as needed; once whatever previous file processing has started with an unknown future completion(*)).
  2. Create a concurrent queue that keeps track of files pending deletion.
  3. Set a timer on a worker thread and periodically iterate the files eligible for copying and try to copy each file. Remove files on success and enqueue them in the pending deletion queue.
  4. On the same worker thread (or a different one with its own timer) iterate all files pending deletion and try to delete each one. Remove files on success.
  5. Keep going until both queues are empty or the world ends.

Moral of the story: checking if a file is locked or not in order to perform some blocking action on it is pointless, nothing stops anything from locking it right after you've performed the check. The way to do this is to simply try and do what you need doing with the file, and if it doesn't work, try again later. If it does, hey, the work is done, great.

(*) If you do know when the file processing finishes then all this is pointless, copy and delete when the previous step has finished.

Upvotes: 1

Greg Kowieski
Greg Kowieski

Reputation: 129

I think you are missing the point of a using statement. Classes with IDisposible can be used with using statements. When the using statement finishes, the "used" class is automatically disposed. A properly written class will close all open operations and dispose the class. So, in short, just do something like the following. Play with the FileAccess and FileShare to meet your needs.

void t()
    {
        using (FileStream _fileStream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (StreamReader sr = new StreamReader(_fileStream))
            {
               // do file operations
            }
        }
    }

Upvotes: 0

Related Questions