How to open a file for independent read/write? - c#

I'd like to open the same file for both reading and writing. The file pointer should be independent. So a read operation should not move the write position and vice versa.
Currently, I'm using this code:
FileStream fileWrite = File.Open (path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
FileStream fileRead = File.Open (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read);
StreamWriter _Writer = new StreamWriter (fileWrite, new ASCIIEncoding ());
StreamReader _Reader = new StreamReader (fileRead, new ASCIIEncoding ());
But that leads to an IOException: "The process cannot access the file because it is being used by another process"

I think I just figured it out myself. In the second File.Open, we're trying to deny other applications write access by specifying FileShare.Read. Instead, we need to allow the first stream to write to the file:
FileStream fileRead = File.Open (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
That's inherently correct, as the reading stream should not care about other people writing to the file. At least I don't get an exception anymore.

I don't have a C# at hand, so I cannot test it.
Can't you just use FileAccess.ReadWrite instead of FileAccess.Read?
Edit: The answer is no. You need to use FileShare to do it.

Related

Change an existing FileStream's 'FileShare' from 'Read' to 'None'

I want to open a file and block others from writing to it, but allow them to read it. Then after some calculations, I want to block reads as well while I write to it, so no process gets a partially written file.
However, while it seems that I can specify creation of a FileStream with either FileShare.Read or FileShare.None, I can't seem to find a way to start out with FileShare.Read and then change to FileShare.None.
The reason I don't want to create a new FileStream (with FileShare.None) is because I don't want any changes to be made to the file while I shift from the old FileStream to the new one.
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
...
}

Best way to upload file using Stream

I am calling REST API which is accepting Stream to upload file from local device, so for that right now I am using following code to get Stream from a file and than closing that stream after it get's uploaded:
var stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
The problem with the above approach is that, until entire file gets uploaded to server user don't have any chance to delete that file because stream of that file is open, what would be the solution to resolve this issue?
If your typical file is reasonably sized (and I'm hoping you won't be uploading 2GB+ files to a REST API), you could always just read the stream into memory and before feeding it to your API, like so:
using (MemoryStream memoryStream = new MemoryStream())
{
using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite)) {
fileStream.CopyTo(memoryStream);
}
memoryStream.Position = 0; // Reset to origin.
// Now use the MemoryStream as you would a FileStream:
api.Upload(memoryStream);
}
Another alternative is to create a temp copy of the file on your hard drive and feed that to the API - but then dealing with cleanup can become a bit cumbersome. FileOptions.DeleteOnClose is your friend and may very well suffice for your purposes, but it still offers no bulletproof guarantees.

How to force exclusive ownership of a file for FileStream

To read a file that's already opened by another process, you usually do something like this.
var outStream = new FileStream(fileName, FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
Is there a way to achieve the opposite effect? In other words, have a program exclusively own the file and make sure that no other processes can read the file until the stream has been closed?
Use FileShare with option None this will give you
Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.
You can read more about it here
Your Code should be :
using (Stream iStream = File.Open("c:\\myFile.txt", FileMode.Open,
FileAccess.Read, FileShare.None))
{
//your code here
}

System.IO effects on OS's file system performance in C#

Is there any performance or any kind of effect on OS's file system permission between the codes below:
FileStream fs = new FileStream(#"file.dat", FileMode.Create, FileAccess.Write);
// and
FileStream fs = File.Create(#"file.dat");
PS: except the usage of a static function issue.
According to reflector, File.Create(path) is just:
new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.None);
and new FileStream(#"file.dat", FileMode.Create, FileAccess.Write) also gets the 4096 buffer - so no, it is just the FileAccess.ReadWrite which is different.
And I don't think FileAccess.Write is much better than FileAccess.ReadWrite because they both locks the file - but I may be wrong.
to comment: because FileShare is set to None and it is write access you want they properly (=I don't know for sure) ain't much of a difference. However, if you wanted Read access the new FileStream(path, mode, access) approach is different because FileShare is set to Read as a default. However, in this case you want to create a file, and therefore it does not make much sense to only read ;-)
If I recall correctly, File.Create("file.dat") just wraps a call to new FileStream("file.dat", FileMode.Create, FileAccess.ReadWrite).

XmlTextReader - Does it lock the file?

This is probably a really simple thing, but I haven't been able to find it, and I'm probably just searching for the wrong thing...
XmlTextReader --> Does it lock the file you're reading? I'm using reader.Read() and that's about it.
When you create a new XmlTextReader providing a string, it will lock the file with a write lock (but not a read lock); however, if you provide it a Stream, it would depend on the stream itself.
FileStream stream = new FileStream(#"myfile.xml", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
XmlTextReader reader = new XmlTextReader(stream);
You can now read without having a lock.

Categories

Resources