copying file, file not disposed - c#

I have the following code for copying file:
var copedFile = ConfigurationManager.AppSettings["PathToFirebirdDB"] + ".001";
using (var inputFile = new FileStream( ConfigurationManager.AppSettings["PathToFirebirdDB"],
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var outputFile = new FileStream(copedFile, FileMode.Create))
{
var buffer = new byte[0x10000];
int bytes;
while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0)
{
outputFile.Write(buffer, 0, bytes);
}
}
}
This code works fine only one time. The next time I get the folowing message:
The process cannot access the file 'D:\Programs\IBExpert\db.fdb.001' because it is being used by another process. System.IO.IOException: The process cannot access the file 'D:\Programs\IBExpert\db.fdb.001' because it is being used by another process.
Why? There are using block.

If you try to reopen the file just after closing it, there is a chance the file is still considered open by the system because it actually is.
A typical reason is that a virus scanner is keeping the file open to ensure it is not infected, this happens in the background and might continue running after you have closed the file yourself.

Probably because you are not closing the files.
BTW why don't you just use File.Copy?

Related

can i make Multiple FileStream objects to one file in the same time?

why in fs2 object throw error ?? i already have written a FileShare.ReadWrite in fs object
FileStream fs = new FileStream("hello.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);
mama();
Console.ReadKey();
}
static void mama()
{
FileStream fs2 = new FileStream("hello.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
fs2.Read(new byte[3], 0, 3);
}
can any one tell me why this error ?
error = The process cannot access the file 'C:\Users\iP\documents\visual studio 2015\Projects\ConsoleApplication32\ConsoleApplication32\bin\Debug\hello.txt' because it is being used by another process.
You're getting that error because you're passing FileShare.None to the second call. If you change that to FileShare.ReadWrite to match the first call, you won't have that problem.
The reason for this is because the FileStream constructor calls CreateFileW underneath, and if you take a look at the documentation for that function, it states:
You cannot request a sharing mode that conflicts with the access mode
that is specified in an existing request that has an open handle.
CreateFile would fail and the GetLastError function would return
ERROR_SHARING_VIOLATION.
You already have an open handle from the first request using FileAccess.ReadWrite as the access mode, which conflicts with FileShare.None in the second call.
Because your code never closes the file and has an open handle to it
If you can, always use the using statement, it will flush and close the file
using(var fs = new FileStream(...))
{
// do stuff here
} // this is where the file gets flushed and closed
If 2 methods are working on the same file, pass the FileStream in
static void mama(FileStream fs )
{
fs .Read(new byte[3], 0, 3);
}

Await for a process to finish execution

I have a process that takes some varying time to execute. The proceeding part of the code depends on its results.
The process creates a printable file (PRN) file. The proceeding section then reads that file and returns its bytes contents.
When i put a breakpoint at the using statement, i get to read the bytes of the created file and return them to where they are being requested. But when i execute as usual, i get the error.
_ The process cannot access the file 'linkToFile' because it is being used by another process _
lbl.PrintSettings.PrinterName = printerName;
byte[] fileBytes = null;
Task.Run(() => { lbl.Print(int.Parse(qty)); }).Wait(2000);
using (var strm = File.Open(outPutPrintFile,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var ms = new MemoryStream())
{
strm.CopyTo(ms);
fileBytes = ms.ToArray();
}
}
return Ok(fileBytes);
I tried to put the part that executes longer in a Task-Wait part but still getting the same error.
Try using Fileshare.ReadWrite instead of FileShare.Read. It's not for some unknown reason as you commented but ReadWrite make sure that further Read/Write operations can be done on opening the file. From your posted code it looks to be the option to choose.

file access exception that I can't shake

I have a third party api that is dropping a file into a directory every 100 miliseconds. Sometimes I can grab it and read it, but I am swallowing a lot of "process cannot access the file because it is being used by another process" exceptions just to get one good read. How do I stop this exception from happening?
Here is the code I am using. I read that using "using" statements should prevent this error, but it's not helping.
string content = "";
string path = "C:\\output.txt";
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.ReadWrite))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b, 0, b.Length) > 0)
{
content += temp.GetString(b);
}
}

What happens to a filestream when the file is deleted by a different process?

In C#, I open a file with FileShare.Delete. This allows me to open the file without restricting other processes from deleting it. For example:
using (FileStream fs = new FileStream(#"C:\temp\1.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
{
int len = (int)fs.Length;
byte[] array = new byte[len];
int bytesRead = fs.Read(array, 0, len);
}
My questions are:
What happens if the file is deleted by a different process after we created the stream, but before we read it? Does the operating system keep a copy of the file until the stream\handle is closed?
Can I rely on reading the deleted file without getting any errors, or the wrong content?
The file is marked for deletion, but is not actually deleted until the last open handle to it is closed, as described in the documentation for DeleteFile.
Note that you cannot open a new handle to a file that is marked for deletion, but the file will still appear in directory listings and cannot be replaced by a file of the same name until it has actually been deleted. This is unlike Unix systems in which the file disappears from the directory (is "unlinked") immediately. As Ben suggests in the comments, you can work around this by renaming and/or moving the file before deleting it.
Also, as MoonRabbit pointed out, you can "delete" an open file using Explorer, but that is because that only moves the file to the recycle bin. The Shift+Delete option to delete a file immediately won't work.
Yes another process can delete the file but you will not get any exception as the pointer to the file on the disk was created so your process will continue reading, but when you retry to open the stream you will get an exception as the entry in the file system does not exist
here a full example to reproduce your case
try to execute this and go to explorer and delete your file
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10000; i++)
{
File.AppendAllText(#"c:\temp\1.txt", Guid.NewGuid().ToString());
}
//read the file
using (FileStream fs = new FileStream(#"C:\temp\1.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
{
while (fs.CanRead)
{
//here I read a chunk of 1000 bytes to let stream open
int len = 1000;
Thread.Sleep(1000);
byte[] array = new byte[len];
int bytesRead = fs.Read(array, 0, len);
}
}
}
}

Enable writing to file that is mapped to memory

I will like to use a memory mapped file to virtualize opening a file on windows when that file is realy on the internet.
So I create the memory mapped file as:
// data that we write to the file. we will get this a tcp
var data = System.Text.Encoding.UTF8.GetBytes("Hello World");
var fileStream = new FileStream("SomeFile.txt", FileMode.Create);
using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024,
MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
{
var viewStream = memoryMapped.CreateViewStream();
viewStream.Write(data, 0, data.Length); // write hello world
}
And I can read from it on windows but not save it:
Note how I was able to open the file (meanwhile the data was on memory and not the hard disk) but the moment I tried saving changes I was not able. So my question is: How could I enable saving changes to that file and be just changing the content in memory of the memory mapped file without actually trying to save anything to disk.
You need to specify the sharing mode when creating the file stream.
var fileStream =
new FileStream("SomeFile.txt", FileMode.Create,
FileAccess.ReadWrite, FileShare.ReadWrite);
Also, you need to dispose of your FileStream when done, e.g. with a using statement.
UPDATE
It worked just fine for me. Using Notepad I had to manually re-open the file, but I could update it while Notepad had it open (Notepad just did not check for external modifications).
Side note: The code writes a bunch of NUL (0x00) bytes to the end of the file. You'll probably want to look into that.
Here's the exact code I used (note the local path to C:\Temp. Change if needed):
static private void WriteMMF()
{
// data that we write to the file. we will get this a tcp
var data = System.Text.Encoding.UTF8.GetBytes("Hello World 2");
using (var fileStream = new FileStream(#"C:\Temp\SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024,
MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
{
var viewStream = memoryMapped.CreateViewStream();
viewStream.Write(data, 0, data.Length); // write hello world
}
}
static void Main(string[] args)
{
Console.WriteLine("Writing MMF");
WriteMMF();
Console.WriteLine("Done. Press a key.");
var ch = Console.ReadKey();
return;
}

Categories

Resources