What's the least invasive way to read a locked file in C# (perhaps in unsafe mode)?
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
.
Can't read all lines in file that being used by another process
use an overload of File.Open in your menuclick event handler like this:
File.Open(@"C:\process.log", FileMode.Open,FileAccess.ReadWrite, FileShare.ReadWrite);
The last param is a value specifying the type of access other threads have to the file.
see this article from msdn
NLog - Allow other processes to read log file
Instead of using File.ReadAllText()
or File.ReadAllTextAsync()
that requires exclusive file-lock:
System.IO.IOException: The process cannot access the file '...' because it is being used by another process.
Then I suggest using FileShare.ReadWrite
to avoid failure when NLog is actively writing to the log-file:
using (var f = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var s = new StreamReader(f))
{
fileContent = s.ReadToEnd();
}
This will also avoid issues for the application that uses NLog for writing to the log-file, as reading with exclusive lock will cause log-writing to fail with logevent being lost and bad performance.
Related Topics
C# Regex: Checking for "A-Z" and "A-Z"
Why Is Webbrowser_Documentcompleted() Firing Twice
There Is No Viewdata Item of Type 'Ienumerable<Selectlistitem>' That Has the Key Country
List Array Duplicates with Count
How to Display Progress During a Busy Loop
Webclient Does Not Support Concurrent I/O Operations
Uniquely Identifying Reference Types in the Debugger
How to Implement One "Catch'Em All" Exception Handler with Resume
How to Implement Inotifypropertychanged in C# 6.0
How to Log All Thrown Exceptions
How to Get Current Regional Settings in C#
Improving/Fixing a Regex for C Style Block Comments