Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a file is currently open or being written to in .NET?

Tags:

c#

.net

io

I am trying to determine whether or not a file is currently open or being written to using C#. I've seen similar SO questions, all with a similar solution as my code, which attempts a File.Open on a file. But when I run the program with the code below, and I also manually have the file open, I get the unexpected result of "File is currently NOT locked". Any thoughts/suggestions/anything I'm missing?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace TestIfFileAccessed
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = @"C:\TEMP\testFile.txt";
            FileInfo filepath = new FileInfo(path);

            if (IsFileLocked(filepath)) {
                Console.WriteLine("File is currently locked");
                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("File is currently NOT locked");
                Console.ReadLine();
            }
        }

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

            try
            {
                stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                //the file is unavailable because it is:
                //still being written to
                //or being processed by another thread
                //or does not exist (has already been processed)
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }

            //file is not locked
            return false;
        }
    }
}
like image 787
kyle_13 Avatar asked Aug 06 '15 19:08

kyle_13


2 Answers

Text files aren't usually locked - their info is usually pulled and loaded into memory, so unless you were trying to access it at the exact same moment that another program is loading the file (which would go very quickly) then you shouldn't have any problems.

Source - Similar question

EDIT: If it is open in word then you will have problems, as Word keeps the stream open. Try opening the file in Word (if you have it) and running your code again, I believe it should work. Otherwise, if you want to see if it's open in Notepad, you would have to scan the current processes running on the system for notepad and check if the process opened the file.

like image 125
Nicholas Ellingson Avatar answered Nov 14 '22 23:11

Nicholas Ellingson


Many text editors don't actually put a file lock on the file. For instance, I use Sublime Text 3 to edit files. I can open an .txt file in Sublime, and open the SAME file in another editor, such as notepad. There is not a filelock on the .txt file.

What is happening is that the file is loaded into memory by the editors when you open them and then closed immediately. They aren't left open. Editors only keep the files open long enough to load them, however, there technically is a lock on the file while the editor is is loading the file into RAM. It just doesn't last very long as this operation is very quick.

You could cause a file lock and see your filelock error as expected if you do filepath.Open(); before you call IsFileLocked(filepath). I would suggest trying this code in your Main method if you want to test this out:

static void Main(string[] args)
{
    string path = @"C:\TEMP\testFile.txt";

    FileInfo filepath = new FileInfo(path);
    Console.WriteLine("Opening \"filepath\"");
    filepath.Open();

    FileInfo filepath2 = new FileInfo(path);

    if (IsFileLocked(filepath2)) {
        Console.WriteLine("File is currently locked");
    }
    else
    {
        Console.WriteLine("File is currently NOT locked");
    }

    Console.WriteLine("Closing \"filepath\"");
    filepath.Close();

    if (IsFileLocked(filepath2)) {
        Console.WriteLine("File is currently locked");
    }
    else
    {
        Console.WriteLine("File is currently NOT locked");
    }
}

I hope this helps to clarify what is going on.

I vow to fall on my sword if this answer turns out to be incorrect and dishonors my family.

like image 42
Nathan M. Avatar answered Nov 15 '22 00:11

Nathan M.