c# check if file is opened or being copied - c#

I have a problem that is driving me mad. Maybe you could help ;)
I'm tracking file changes on the folder with FileSystemWatcher and copy changed files to another folder. I don’t want to copy the file until it is done being saved. I cannot find a solution that works at the same time for all 3 scenarios below:
1) New file being copied into the folder
2) Existing file being overwritten by copying new one
3) File is opened by another process (i.e. Word)
I have tried IsFileLocked method from the thread below.
c# check if file is open
It will work for copying but the problem is that function will always return TRUE for opened OFFICE files (maybe for some others as well).
I also tried to check in the loop if the file size changes but it’s seems to be impossible as FileInfo.Length always return the target size (even though file is still being copied).
I'm using that function to check if file is in use
public static bool IsFileLocked(string path)
{
FileInfo fileInfo = new FileInfo(path);
FileStream stream = null;
try
{
stream = fileInfo.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (UnauthorizedAccessException)
{
// file created with readonly flag
return false;
}
catch (FileNotFoundException)
{
return false;
}
catch (IOException ex)
{
int errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
bool islocked = errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
return islocked;
}
finally
{
if (stream != null)
{
stream.Close();
stream.Dispose();
}
}
//file is not locked
return false;
}
Do you know how to distinguish if it's opened by some application or being copied?

Related

While deleting file error occurs : Access to the path is denied

I am trying to delete File from the folder for which Full control is assigned but still sometime users get Access Denied for that folder.
This happens sometimes not every time.
Note : before deleting we check if file is in use. Following are two functions.
Delete File :
public static Boolean DeleteFile(string filePath)
{
bool isFileInUse = false;
if (File.Exists(filePath))
{
FileInfo currentFileInfo = new FileInfo(filePath);
if (!IsFileLocked(currentFileInfo))
File.Delete(filePath);
else
isFileInUse = true;
}
return isFileInUse;
}
IsFileLocked :
private static Boolean IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
//Don't change FileAccess to ReadWrite,
//because if a file is in readOnly, it fails.
stream = file.Open
(
FileMode.Open,
FileAccess.Read,
FileShare.None
);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
Can anyone tell me even after giving full control why sometimes this error occurs ??
Note : We first need to check compulsory if file is in use while we try to delete it.

Check file accessibility .NET Core

I would like to check if file is accessible.
I list file using
IFileProvider provider = new PhysicalFileProvider(_settings.appSettings.sourceDirectory);
var files = provider.GetDirectoryContents("");
Then i got a list of IFileInfo and not FileInfo
I would like to check if the file is not in use or in creation by a scanner or something like that (The program is a directory scanner (in the scanner reception folder) which send these files to a Web API)
In .NET 4.5 I could do this :
public static bool IsFileLocked(this FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
But i can't do this in .NET Core 2 or 1
I can use the stream reader, but I need performance to read a maximum of files (this directory can get 1000 files every 30 seconds)
Thanks

Is there a way to check that a file is in use

Using c#, is there a way to check that a file is in use. More specifically, I need a way to monitor a directory of .wav files and see which sound file has been loaded.
Note. It can be loaded by different applications.
I've had a look at Core Audio.. but I cannot seem to find an answer there.
I've also tried to code that if the file is locked but that also doesnt provide a solution. So if you know of a way to determine which sound file (.wav) is currently being played, please comment.
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
Here is the reference link : File is in Use
Hope it helps.

Delete functions deletes even when calling app is closed

I'm stuck with a weird problem (which is probably my lack of knowledge), I present the offending code:
try
{
f.Delete();
fTemp.MoveTo(f.FullName);
Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
}
catch (IOException ex)
{
Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName);
Environment.ExitCode = 1;
}
f and fTemp are FileInfo objects. So if I run this with code where f is a video file playing in a mediaplayer it throws the exception. That works fine and as expected. Now when I close the mediaplayer it deletes the file!? Even though my application is long closed. Even when I close Visual Studio it still deletes the file, when I close the mediaplayer. As if some callback is being setup somewhere to make sure the file gets deleted at some point. This offcourse in unwanted behaviour. But I can't figure out what exactly goes wrong...
Result for now :
if (!IsFileLocked(f))
{
try
{
f.Delete();
fTemp.MoveTo(f.FullName);
Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
}
catch (IOException ex)
{
Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName);
Environment.ExitCode = 1;
}
catch (UnauthorizedAccessException ex)
{
Environment.ExitCode = 2;
Console.WriteLine("ERROR: Output file is locked > {0}", f.FullName);
}
}
else
{
Environment.ExitCode = 3;
Console.WriteLine("ERROR: Couldn't delete file was locked");
}
I know I still can do better between Delete and MoveTo, but I'll take my changes for now, shotgun coding.....
You are getting the IOException because the file cannot immediately be deleted or written to. However, when you call Delete(), it seems the file is getting called for deletion.
Though the media player stops the file from being deleted while it is open, the file is still marked for deletion when it closes, regardless of whether your program is running. So when the media player closes the file is deleted.
You can check if the file is in use with the following code, taken from here. Make the Delete and Copy conditional on it not being locked, and you should be good.
try
{
if(!IsFileLocked(f))
{
f.Delete();
fTemp.MoveTo(f.FullName);
Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
}
}
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
From the Windows SDK:
The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED.
As far as I understand, you want your program to wait until the file can be deleted and then delete it and move the other file.
To do this, you could check, if there is a handle open on the file, but this needs unmanaged code. Another way would be to use the methode from the answer of this question: Is there a way to check if a file is in use?
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
Before you start to delete the file you could
A) loop until the file can be deleted
while(IsFileLocked(f)) { Thread.Sleep(100); }
or B) cancel
if (IsFileLocked(f)) { return; }
If you choose A or B depends on your requirements.

Is there a way to programmatically check if a Excel file is opened

I want to check whether a particular Excel file is already opened. Otherwise when I reopen same file in my C# program it is opening in read only format. Is there any way to find out if the file is already open?
If the file if opened by another program this code can help you figure it out, but you won't be able to open it
<!-- language: c# -->
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
(BUt you can't do anything with it, the file must be closed from the program, which opened it)

Categories

Resources