How to force exclusive ownership of a file for FileStream - c#

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
}

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 open a file in memory?

I have see this term branded around but I don't really understand how you open a file in memory.
I have the files written to disk in a temp location but this needs cleaning when a certain form closes and I can't do it when it's open. It's a must that this folder gets emptied. I was wondering if I opened files in memory instead whether it would make a difference?
MemoryStream inMemoryCopy = new MemoryStream();
using (FileStream fs = File.OpenRead(path))
{
fs.CopyTo(inMemoryCopy);
}
// Now you can delete the file at 'path' and still have an in memory copy
I think you want to work with Memory Mapped files added recently to .NET 4.
http://blogs.msdn.com/b/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx
Memory Mapped Files .NET
I think it means to read the content of that file into memory as a whole and then close the connection to the file. Assuming it's a file that's not too big you could just read it into a byte[]:
byte[] fileContent = File.ReadAllBytes(fileName);
If it's a text file read it into a string using
string fileContent = File.ReadAllText(fileName);
Once you've done that use a StreamReader to read it later as you would a file on disk.
You can use DeleteOnClose parameter of FileStream constructor:
FileStream fs = new FileStream("<Path Here>", FileMode.Create,
FileAccess.ReadWrite, FileShare.None, 1024, FileOptions.DeleteOnClose);
and the file will be deleted when closed.

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).

How to open a file for independent read/write?

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.

Categories

Resources