How to open an already opened file using .net StreamReader?

I have some .csv files that I use as part of a test bench. I can open them and read them without any problems if I have not already opened the file in Excel, in which case I get an IOException :

System.IO.IOException: The process cannot access the TestData.csv file because it is being used by another process.

This is a snippet from the test bench:

 using (CsvReader csv = new CsvReader(new StreamReader(new FileStream(fullFilePath, FileMode.Open, FileAccess.Read)), false)) { // Process the file } 

Is this a limitation of StreamReader? I can open the file in other applications (e.g. Notepad ++), so it cannot be an O / S problem. Maybe I need to use some other class? If anyone knows how I can get around this (other than closing excel!), I would really appreciate it.

+39
file readonly streamreader
May 22 '09 at 1:19 p.m.
source share
5 answers

As Jared says, you cannot do this if another object that has an open file does not allow shared reads. Excel allows co-read, even for files that are open for writing. Therefore, you must open the stream with the FileShare.ReadWrite parameter.

The FileShare parameter is often misunderstood. It indicates what other file openers can do. This applies to both past and future developers. Think of the fact that FileShare is not a retroactive ban on previous openers (such as Excel), but a restriction that should not be violated with the current Open or any future Open.

In the case of the current attempt to open the file, FileShare.Read says that "open this file for me successfully only if the previous openers were read-only." If you specify FileShare.Read in a file that is open for writing in Excel, your open will fail because it will violate the restriction because Excel opens it for writing.

Since Excel has an open file for writing, you must open the file with FileShare.ReadWrite if you want your opening to be successful. Another way to think about the FileShare option: it indicates "access to the file of another guy."

Now suppose another scenario in which you open a file that is not currently open by any other application. FileShare.Read says that "future openers may open a read-only file."

Logically, these semantics make sense - FileShare.Read means that you do not want to read the file if the other guy is already writing it, and you do not want the other guy to write the file if you already read it. FileShare.ReadWrite means that you are ready to read the file, even if the other guy is writing it, and you have no problem letting the other opener write the file while reading it.

In no case does this allow several authors. FileShare is similar to the IsolationLevel database. Your desired setup here depends on the required β€œapprovals”.

Example:

 using (Stream s = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { ... } 

or,

 using (Stream s = System.IO.File.Open(fullFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { } 



Addendum:

The documentation for System.IO.FileShare is a bit subtle. If you want direct facts, go to the documentation for the CreateFile Win32 function , which better explains the concept of FileShare.

+136
May 22 '09 at 14:05
source share

EDIT

I'm still not 100% sure why this is the answer, but you can fix this problem by passing FileShare.ReadWrite to the FileStream constructor.

 using (CsvReader csv = new CsvReader(new StreamReader(new FileStream(fullFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)), false) { ... } 

My curiosity holds me at the moment, and I'm trying to understand why this is a specific answer. If I find out later, I will update this information.

The best documentation seems to be in the CreateFile function. This .Net function is called under the hood to open the file (creating the file is a bit wrong). It has the best documentation on how the collaborative aspect of opening a file works. Another option is to just read Chiso's answer

+13
May 22, '09 at 13:22
source share

If another process has a file open, you can often use File.Copy and then open a copy. Not an elegant solution, but a pragmatic one.

+5
May 22 '09 at 13:25
source share

Another problem is that if you open FileStream with FileShare.ReadWrite , subsequent openings of this file should also indicate FileShare.ReadWrite , or you will get the error "Another process is using this file."

0
Oct 05
source share

Using System.Diagnostics;

You can just call Process.Start ("filename & Path")

Not sure if this helps, but here is what I just used to implement the Preview PDF button on our intranet.

-6
Nov 29 '12 at 13:16
source share



All Articles