Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I read a file even when getting an "in use by another process" exception?

In VB.NET or C#, I'm trying to read the contents of a text file that is in use by another program (that's the point, actually, I can't stop the program or it stops writing to the text file, and I want to periodically read out what is currently in the text file in another program).

This is the code I'm using (VB.NET)

Dim strContents As String
Dim objReader As StreamReader
objReader = New StreamReader(FullPath)
strContents = objReader.ReadToEnd()
objReader.Close()

Or in C#:

var objReader = new StreamReader(FullPath);
var strContents = objReader.ReadToEnd();
objReader.Close();

The above, however, throws the IO exception "The process cannot access the file 'file.txt' because it is being used by another process." Are there any workarounds in this scenario?

like image 261
Frustrated Guy Avatar asked Dec 09 '10 16:12

Frustrated Guy


People also ask

How do you fix the process Cannot access the file because it is being used by another process C #?

Process cannot access file because it is being used by another process error message. To resolve this error: Press Ctrl + Alt + Delete, then click Task Manager. Ensure you're on the Processes tab.

How do you close a file that is used by another process?

Now browse for the application that you used to open the "file in use." For example, if you were viewing a document, look for Microsoft Word. Once you find the process, select it and click End task in the bottom right. This will close all instances of the program.

How check file is open or not in C#?

try { using (Stream stream = new FileStream("MyFilename. txt", FileMode. Open)) { // File/Stream manipulating code here } } catch { //check here why it failed and ask user to retry if the file is in use. }


4 Answers

FileStream logFileStream = new FileStream("c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);

while (!logFileReader.EndOfStream)
{
    string line = logFileReader.ReadLine();
    // Your code here
}

// Clean up
logFileReader.Close();
logFileStream.Close();

Original source for code

like image 153
Development 4.0 Avatar answered Oct 13 '22 19:10

Development 4.0


I'll do the fish. The FileShare mode is critical, you must allow for write sharing. That cannot be denied since the process that is writing the file already obtained write access. The StreamReader() constructor uses FileShare.Read and doesn't have an option to use a different value. Using the StreamReader(Stream) constructor is instead is indeed the workaround.

Beware however that this sharing mode also has implications for your code. You cannot predict when the other process flushes the file. The last line you read may contain only part of a line of text. When it flushes is file buffer again, later, you'll get the rest of the line. Clearly this can mess up your logic.

like image 22
Hans Passant Avatar answered Oct 13 '22 18:10

Hans Passant


It depends on the FileShare mode with which the file was opened by the other application that is appending to the file. When the other application was opening the file, it specified a FileShare mode for other applications to access the file. This FileShare mode could have been read, write, both, delete, all of these, or none.

You have to specify the very same FileShare mode that the other application specified. If the other application allowed only reading, use FileShare.Read; if it allowed both reading and writing, use FileShare.ReadWrite.

StreamReader uses only FileShare.Read mode, so you can already assume that that's not the right one. So, try ReadWrite, like so:

FileStream fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader reader = new StreamReader(fs);
like image 41
Barbara Avatar answered Oct 13 '22 20:10

Barbara


Not sure how this will behave with an already open file, but this will prevent your application from locking it:

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);

Hope it helps!

like image 32
Brosto Avatar answered Oct 13 '22 18:10

Brosto