File.Replace - File is being used by another process error - c#

Question background:
I am attempting to overwrite the contents of one specified file with the contents of another specified file within a folder on my C drive using the following 'File.Replace' method:
//'null' has been set to the 'backup file' parameter as I do not need this.
File.Replace(fileOnesLocation, filesTwosLocation, null);
The error:
I have the above method wrapped in a try catch and am currently receiving the following error:
System.IO.IOException: The process cannot access the file
because it is being used by another process.
Can anyone point me in the right direction of whats going wrong here?

If you want to avoid this errors, you could try doing something like this answer, create a method to check whether your file is open or not.
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;
}

If the file is open either by you or another logged in user then you may not be able to open it.
check in task manager for processes by users and close the file.

This error is often caused when the file being replaced or written to is open by you or someone/thing while the code is running.

Related

Need to check whether a particular text file is in open state ... if yes need to close the editor using c#

I have placed a text file in c:\my_files\test1.txt. Using C# I need to check whether the file is in an open state. If it is, I need to close the editor.
In the below code it doesn't go to the catch block if the file is in open state.
string path = #"c:\my_files\test1.txt";
FileStream stream = null;
try
{
stream = File.Open( path, 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;
Console.WriteLine("true");
}
finally
{
if (stream != null)
stream.Close();
}
You cannot determine whether the Notepad.exe application has a file opened in memory - it does not retain an open file stream. You might be able to check that the Notepad application processes window title has the name of the file in it, but it does not have the file path, so this is extremely fragile.
Since Notepad does not have the file open, its not meaningful to attempt to close the file. You can try to close Notepad if you think the file is has copied to its memory buffer is the one you think it is ...

File is being used by another process in c#

I am trying to delete a file in C#, however I am receiving a message that the file is used from another process. What I want to do is to check if the files exists and close it. I am using the following function in order to check if the file is open:
public static bool IsFileInUse(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentException("'path' cannot be null or empty.", "path");
try
{
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { }
}
catch (IOException)
{
return true;
}
return false;
}
and I am trying when the file is in use to close it:
bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (File.Exists(file))
{
File.Delete(file );
}
I got issues in File.Create line, I am receiving the message:
File is being used by another process.
EDIT: I am trying to use lock approach in order to delete the file. Am I suppose to delete the file inside a lock statement? How Can I use properly the lock statement?
Why do you suppose that a reading operation will fail if file is in use while a writing operation will not? File.Create() will fail exactly as new FileStream() failed before...
See also IOException: The process cannot access the file 'file path' because it is being used by another process.
Note that your check will fail if the other process didn't open that file exclusively (check FileShare enumeration): file may be open for shared reading, writing and sometimes even for deleting (for example you may be able to read concurrently but not writing however the other process may let you delete that file...).
To close an open file can be really disruptive for the other process, it may crash, nicely handle the problem or...anything else (silently ignore that error and produce random output, open file again and so on...) Is it possible to do it in C#? Yes with some P/Invoke...
1) Let's find the handle for the file you want to unlock. Use NtQuerySystemInformation() and enumerate all handles until you find the one that refers to that file.
2) Duplicate that handle to be valid in your own process using DuplicateHandle().
3) Close just create handle specifying DUPLICATE_CLOSE_SOURCE, it will close both your handle and the original one (of course if your process has enough permissions).
4) Check if file is really closed calling NtQuerySystemInformation() again, if not then you may need to directly close its parent process.
In your code, you don't do anything with the IsFileInUse result.
This File.Create(file ).Close(); will also not close a file that is opened by another process. You need to close the process that has the file open, and if it is your own app, close the file handle before trying to delete the file.
bool checking = IsFileInUse(file );
File.Create(file ).Close();
if (!checking)
{
if (File.Exists(file))
{
File.Delete(file );
}
}
You have no need to check if the file exists, just try do delete it:
https://msdn.microsoft.com/en-us/library/system.io.file.delete(v=vs.110).aspx
If the file to be deleted does not exist, no exception is thrown.
Try and check the exception
try {
File.Delete(file);
}
catch (IOException) {
// File in use and can't be deleted; no permission etc.
}

check if a text file is opened in notepad

how to find whether specific .txt file is opened in notepad?
I have tried solutions mentioned here
Is there a way to check if a file is in use?
But they work fine for Word and pdf file but not working for txt file opened in Notepad.
here is code I have wrote.
public bool IsFileOpen(string strFileName)
{
bool retVal = false;
try
{
if (File.Exists(pstrFileName))
{
using (FileStream stream = File.OpenWrite(pstrFileName))
{
try
{
}
catch (IOException)
{
retVal = true;
}
finally
{
stream.Close();
stream.Dispose();
}
}
}
}
catch (IOException)
{ //file is opened at another location
retVal = true;
}
catch (UnauthorizedAccessException)
{ //Bypass this exception since this is due to the file is being set to read-only
}
return retVal;
}
am i missing somthing here.??
My requirement:
I have application which works similar to VSS. When user checks out specific file and opens ,and try to check in the same, while it has opened. Application is suppose to throw a warning message.For that i have used the above functionality.Its working fine for word and pdf.
To expand on my comment. A file is only locked if a handle is kept open by an application. Word for example will open the file, read in the stream and maintain the handle so that other applications cannot delete that file while the user is working on it.
Notepad, and other applications, just open the file, read in the entire stream and then close the file releasing the lock they have. This means that the file is no longer locked and can be edited by another application or even deleted and Notepad will not care as it has its own copy in memory.
You could try and hack around with getting instances of Notepad and checking if a file is open but this is ultimately not a great idea. If the file is not locked then you should be free to do what you want with it.
This is a hack solution I just came up with, but it should work for you. This makes use of System.Diagnostics.
Process[] processes = Process.GetProcessesByName("notepad");
for (int i = 0; i < processes.Length; i++)
{
Console.WriteLine(processes[i].MainWindowTitle);
if (processes[i].MainWindowTitle.Equals("myFile.txt - Notepad"))
{
Console.WriteLine("The file myFile is Open!");
}
}
Console.ReadLine();
Hopefully that should do the trick. My example looks to see if an instance of notepad is open with the window title "myFile.txt - Notepad". The window name is always "filename.extension - Notepad" so you can handle that however you might need to.
I suppose you could make a call to System.IO.File.GetLastAccessTime(filePath). You could then poll the file every so often and when the access time changes you know the file has been opened, you can then fire an event that the file has been opened. See Jeffs post here:
Detect File Read in C#
You could also do this using the following tactic: It seems that notepad does hold some kind of lock on the hosting folder (try to delete the folder and you'll see you can't).
you could use the following code Using C#, how does one figure out what process locked a file? to check list of processes that lock the folder.
one of the processes will be your notepad.
you could them compare by Title as another answers mentioned.
if you're issuing the open of the file - you could save the PID and comapre it with one of the processes that returned.

How to know if a folder of file is being used by another process?

I know there are tens of questions already about "the file being used by another process". But they all have the problem of trying to read a file or write to a file that is already being used by another process. I just want to check to see if a file is being used by another process (no IO action after that).
I didn't find the answer elsewhere.
So, how can I know if a file or folder is being used by another process in C#?
As you describe in the question the only way is to try to open the file first to see if it used by another process.
You can use this method I implemented sometime ago, the idea is if the file exists then try to open the file as open write, and so if failed then the file maybe is used by another process:
public static bool IsFileInUse(string fileFullPath, bool throwIfNotExists)
{
if (System.IO.File.Exists(fileFullPath))
{
try
{
//if this does not throw exception then the file is not use by another program
using (FileStream fileStream = File.OpenWrite(fileFullPath))
{
if (fileStream == null)
return true;
}
return false;
}
catch
{
return true;
}
}
else if (!throwIfNotExists)
{
return true;
}
else
{
throw new FileNotFoundException("Specified path is not exsists", fileFullPath);
}
}
This post might help:
How to check for file lock?

Problem with reading text file

I got a problem with reading a text file, it's not the reading it's self that is a problem it is when I should read it.
I got a server program (made by an external company so I got no control over it) where you can put files in. The server see's a new file has arrived reads it and does things with it and then he puts a result back. So I'm waiting for the file to be ready, but I can't read it to early cause I don't know if it exists already. So I'm doing this:
while (IsFileLocked(file))
{
Thread.Sleep(25);
}
private bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
Now this really helps to check if the file is readable and I never get any IOExceptions anymore when I'm reading. Now I start the reading but sometimes I just read an empty file. And I'm pretty sure it shouldn't be empty. It's not a bug of the server program (I'll explain later).
Here is the code where the problem starts:
using (StreamReader streamReader = file.OpenText())
{
while (!streamReader.EndOfStream)
{
// here starts the reading
}
}
But when I use this code I don't get the problem:
using (StreamReader streamReader = file.OpenText())
{
Thread.sleep(1000);
while (!streamReader.EndOfStream)
{
// here starts the reading
}
}
So my guess is that the file is empty when I can open it but it has no text in it.
I changed the Thread.sleep to 100 miliseconds and then I get the problem again. When I changed it to 500 the problem was solved again.
Now my software needs to run on a lot of different computers so I don't know how fast they are, but I'm afraid if I set the timer to low I might get problems on other computers. But I don't want my users to be waiting for there info to long.
Is waiting the only option or is there another way?
Will there be a problem on other computers with different hardware configuration?
Edit: I tried FileSystemWatcher, and it is not the solution!
Waiting for a file to be created in C# - SO
The tool you need to add is a FileWatcher (see MSDN System.IO.FileWatcher). This will allow you to monitor activity and add event handlers to response to file events. You can respond to file created by adding a handler for file changed.
Simply you can do like this:
http://olioul.wordpress.com/2012/01/08/4-text-readwrite-in-text-document/

Categories