Cannot Implicitly Convert Type 'System.Collections.Generic.Ienumerable
<Anonymoustype#1>' to 'System.Collections.Generic.List<String>

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



Leave a reply



Submit