Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the least invasive way to read a locked file in C# (perhaps in unsafe mode)?

Tags:

c#

file

locking

I need to read a Windows file that may be locked, but I don't want to create any kind lock that will prevent other processes from writing to the file.

In addition, even if the file is locked for exclusive use, I'd like to see what's inside.

Although this isn't my exact use case, consider how to read a SQL/Exchange log or database file while it's in use and mounted. I don't want to cause corruption but I still want to see the insides of the file and read it.

like image 643
makerofthings7 Avatar asked Aug 24 '10 20:08

makerofthings7


People also ask

How do I unlock a .Lock File?

Right-click on the file. In the menu that appears, select Lock File. To unlock, right-click the file and select Unlock File.

What is struct flock?

Data Type: struct flock. This structure is used with the fcntl function to describe a file lock. It has these members: short int l_type. Specifies the type of the lock; one of F_RDLCK , F_WRLCK , or F_UNLCK .

How do you check if the file is locked?

The easiest way to tell if a file is locked is when the operating system tells you so after you've tried to modify it or move it from where it's at. For example, if you open a DOCX file for editing in Microsoft Word, that file will be locked by that program.


2 Answers

You can do it without copying the file, see this article:

The trick is to use FileShare.ReadWrite (from the article):

private void LoadFile() {     try     {         using(FileStream fileStream = new FileStream(             "logs/myapp.log",             FileMode.Open,             FileAccess.Read,             FileShare.ReadWrite))         {             using(StreamReader streamReader = new StreamReader(fileStream))             {                 this.textBoxLogs.Text = streamReader.ReadToEnd();             }         }     }     catch(Exception ex)     {         MessageBox.Show("Error loading log file: " + ex.Message);     } }  
like image 189
Alistair Evans Avatar answered Sep 19 '22 12:09

Alistair Evans


The accepted answer is not correct. If the file is really locked, you cannot just change the file share. This would work if the lock has been set with this fileshare option too but it does not mean that it is the case. In fact, you can test @CaffGeek solution pretty easily by opening the file without the FileShare.ReadWrite and than trying to open it with this flag to ReadWrite. You will get that the file is using by another process.

Code:

string content; var filePath = "e:\\test.txt";  //Lock Exclusively the file var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);  //CaffGeek solution using (FileStream fileStream = new FileStream(         filePath,         FileMode.Open,         FileAccess.Read,         FileShare.ReadWrite)) {     using (StreamReader streamReader = new StreamReader(fileStream))     {         content = streamReader.ReadToEnd();     } } 

As you can see, it crashes. This result is the same with any FileStream method like the File.Open. It will crash what ever you put for FileShare during the open stage.

//OPEN FOR WRITE with exclusive var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);   //OPEN FOR READ with file share that allow read and write var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash 

Copying the file is not also an option. You can try it your self by opening the file exclusively and try to copy the file on Windows Explorer or by code:

var filePath = "e:\\test.txt"; var filePathCopy = "e:\\test.txt.bck";  //Lock the file var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);  File.Copy(filePath, filePathCopy); var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using (var reader = new StreamReader(x)) {     content = reader.ReadToEnd(); }  r.Close(); File.Delete(filePathCopy); 

This code crash when you hit the File.Copy line. The exception is the same as before : file is being using by another process.

You need to kill the process that has the lock of the file if you want to read it OR if you have the source code of the file that is locking the file to change this one to use FileShare.ReadWrite instead of just FileShare.Write.

like image 44
Patrick Desjardins Avatar answered Sep 21 '22 12:09

Patrick Desjardins