Blocking a file while writing it using FileStream append mode in C# - c#

I'm appending data to a file using Filestream buffer, see below:
using (FileStream filestream = new FileStream(stringPathFile, FileMode.Append, FileAccess.Write, FileShare.None))
{
filestream .Write(stuff.buffer, 0, stuff.bytesRead);
}
As debuging, when writing a larger file, I saw the file being written to the destination by every 4096 bytes, and i was able to move the file to somewhere else. How do I block file being moved around until i complete writing to the file?
Thanks

Use FileShare.ReadWrite instead of FileShare.None.
EDIT: after some testing in VB.NET 2010 (I don't have access to C# at the moment), I replicated your problem. What seems to fix the problem is avoid using using...
FileStream filestream = new FileStream(stringPathFile, FileMode.Append, FileAccess.Write, FileShare.None)
{
filestream.Write(stuff.buffer, 0, stuff.bytesRead);
}

Related

C# how to open file for writing and allow others to read it

I'm doing the following:
var streamWriter = new FileStream("foo.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
Thus, I want to open foo.bin (or create it if it does't exist); I want to read and write to it from streamWriter, and I want others to be able to open it for reading. But when I subsequently do this:
var streamReader = File.OpenRead("foo.bin");
I get the exception The process cannot access the file 'foo.bin' because it is being used by another process.
What gives? I did want others to be able to open it for reading...
This is because File.OpenRead is the same as FileStream reader = new FileStream("file", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); and a prior FileStream has it opened for reading and writing. As such the fileshare on it will fail. Try this instead of File.OpenRead()
FileStream reader = new FileStream("File", FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
Heres a link to the documentation on File.OpenRead
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.openread?view=net-5.0
this link is good to start
[blog]: https://csharp.net-tutorials.com/file-handling/reading-and-writing/ "click here for solution"
for same stream::
[blog]: Read and write to a file in the same stream "click here for solution

C# FileStream and Windows Memory cache

I'm working on an application that should store some PDF for later printing. I have an implementation that is checking what size the PDF is and according to the size I choose between Memory or File Streams (<2GB = MemStream and >2GB = FileStream).
When I am using the FileStream the performance varies and I just noticed that this is caused by the Windows Memory Cache. Basically everything i am using to write/read to/from a FileStream will get into this cache and after saving 6 PDFs I get really low performance (30 seconds compared to 60s+)
I declare my FileStream in the following way:
FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 524288, FileOptions.WriteThrough))
I just added the WriteThrough option but it does not seem to fix the issue.
Is there a possibility that after I save the file to disk and close/dispose the FileStream I get the cache memory cleared?
Thank you in advance!
__________edit___________
adding code snippets.
loadStream = new FileStream(#"C:\temp\FileStream_test.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 524288);
request.InputStream.CopyTo(loadStream);
loadStream.Flush();
loadStream.Position = 0;
and 2nd one
using (var mimePDL = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 524288, FileOptions.WriteThrough))
{
mimeParts[contentID].Content.DecodeTo(mimePDL);
mimePDL.Position = 0;
mimePDL.Flush(true);
mimePDL.Close();
mimePDL.Dispose();
}
And for the first one I dispose of it this way
loadStream.Close();
loadStream.Dispose();
File.Delete(((FileStream)loadStream).Name);
In my opinion you shouldn't store PDFs in memory if you aren't manipulating them.
After manipulations, just save the file and dispose the stream.
If you need some metadata, just take them in your application instead of the entire file.

Is there a built in way to create a file if it doesn't exist when opening one?

I need to open a file to write some text to it, is there a built in way where the file is created if it doesn't exist already?
I want to append to this file, and avoid locking it while it is open. But I will be writing to the file if there is an exeption in a loop like:
try
{
}
catch()
{
write to file
}
You can use File.Open with a FileMode.OpenOrCreate, FileMode.Append.
using (FileStream fs = File.Open(path, FileMode.Append))
{
// use fs
}
In either case, if the file has been opened with FileAccess.Write or FileAccess.ReadWrite, a new file will be created if one doesn't exist.
var fileStream = new FileStream(#"c:\file.txt", FileMode.Append);
This will create the file, if it doesnt exist already.

Reading / Writing text file repeatedly / simultaneously

How do I read and write on a text file without getting the exception that "File is already in use by another app"??
I tried File.readalltext() and File.Appendalltext() functions..I'm just starting out with filestream.
Which would work out best in my scenario? I would appreciate some code snipplets too ..
Thanks
This is all to do with the lock and sharing semantics that you request when opening the file.
Instead of using the shortcut approach of File.ReadAllText(), try looking into using a System.IO.FileStream and a System.IO.StreamReader / System.IO.StreamWriter.
To open a file:
using (var fileStream = new FileStream(#"c:\myFile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamReader = new StreamReader(fileStream))
{
var someText = streamReader.ReadToEnd();
}
Note the FileShare.ReadWrite - this is telling the stream to allow sharing to either other readers or other writers.
For writing try something like
using (var fileStream = new FileStream(#"c:\myFile", FileMode.Create, FileAccess.Write, FileShare.Read))
using (var streamWriter = new StreamWriter(fileStream))
{
streamWriter.WriteLine("some text");
}
Note the FileShare.Read - this is telling the stream to allow sharing to readers only.
Have a read around the System.IO.FileStream and its constructor overloads and you can tailor exactly how it behaves to suit your purpose.
You need to make sure the file is not being used by any other application.
With your own application, you cannot read from a file multiple times without closing the stream between reads.
You need to find out why the file is in use - a tool like FileMon can help finding out.

Easiest way to read text file which is locked by another application

I've been using File.ReadAllText() to open a CSV file, but every time I forget to close the file in Excel, the application throws an exception because it can't get access to the file.
(Seems crazy to me, I mean the READ in ReadAllText seems pretty clear)
I know that there is File.Open with all the bells and whistles, but is there an 'intermediate' method which doesn't involve messing around with buffers and char arrays?
I think you just want the following:
using (var fileStream = new FileStream("foo.bar", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var textReader = new StreamReader(fileStream))
{
var content = textReader.ReadToEnd();
}
The FileAccess.Read parameter is what is important, to indicate that you only want to read the file. Of course, even to do this, the file must have been opened by Excel in read-share mode (see the FileShare enum in .NET). I haven't tested, so I can't guarantee that Excel does this, though I would expect it does.
[edit]
Here's a method version:
static string ReadAllText(string file)
{
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var textReader = new StreamReader(fileStream))
return textReader.ReadToEnd();
}
If you want to specify file sharing flags in order to open a file that's in use, you're stuck with File.Open().

Categories