File.Copy method makes file inaccessible - c#

I am struggling with this for some time now. I can not access a file after I call File.Copy method. Here is what I tried:
File.Copy(sourceFile, destinationFile, true);
FileStream fs = File.Open(destinationFile, FileMode.Open);
I am getting UnauthorizedAccessException on the second line. It says: Access to the path ... is denied. I have also tried suggestion stated here but that didn't work.
Any help is appreciated.
EDIT: Here is what I found out. If I do this:
File.Copy(sourceFile, destinationFile, true);
FileStream fs = File.Open(destinationFile, FileMode.Open, FileAccess.Read);
It doesn't throw exception. The file I am trying to access is read only. So, I tried to remove read only attribute like this:
File.Copy(sourceFile, destinationFile, true);
FileInfo fileInfo = new FileInfo(destinationFile);
fileInfo.IsReadOnly = false;
FileStream fs = File.Open(destinationFile, FileMode.Open, FileAccess.ReadWrite);
And I get the same exception as before. By the way, I checked if I can open file manually and edit it, and I can. Of course, when I uncheck read only check box. I have also checked file attributes in windows explorer while debugging, right after the third line, and the file is no longer read only. Having all that in checked, I don't understand why is the exception being thrown on the fourth line.

Are you sure it's ONLY files copied using File.Copy that you can't open, and not every file in the target folder? And is this a regular NTFS folder, or network share?
If you are running an antivirus or security software, try disabling it. After a file is created they will often open a file to scan it.
Update
According to http://msdn.microsoft.com/en-us/library/b9skfh7s.aspx - UnauthorizedAccessException thrown by File.Open will not give the message 'Access to the path... is denied'. (edit: I can't see that message for File.Copy either, so this might be wrong)
I suspect it is your File.Copy that fails with that exception, and you don't have rights to read the source file, or write the target file. You're probably looking at the highlighted source code line, which shows the next line to be exectued.
So - maybe your copy fails, not the File.Open ?

Try this!
private bool CheckFileHasCopied(string FilePath)
{
try
{
if (File.Exists(FilePath))
{
using (File.OpenRead(FilePath))
{
return true;
}
}
else
{
return false;
}
}
catch (Exception)
{
Thread.Sleep(2000);
return CheckFileHasCopied(FilePath);
}
}
if (CheckFileHasCopied(destinationFile)) { File.Delete(sourceFile); }

Related

DirectoryNotFoundException even when file does exist

This is the code:
string file = Path.Combine(Environment.CurrentDirectory, "test.txt");
if (!File.Exists(file)) {
File.CreateText(file); // will throw always
}
using (var writer = new StreamWriter(file)) { // will throw always
//...
}
This will throw a DirectoryNotFoundException if the file doesn't exist and if it attempts to create it, and if the file does exist, then it will throw DirectoryNotFoundException when trying to use StreamWriter. I don't believe this code is wrong, so I am at a loss at what is the problem.
Update
The value of file is /tmp/test.txt. Yes, it always is throwing, the exception is
System.IO.DirectoryNotFoundException: Could not find a
part of the path '/tmp/test.txt'
Update
A reboot has fixed this. I have no idea why this was being caused, but it might've simply been an IDE issue.
You are opening a file with
File.CreateText(file);
File.CreateText(String) Method
Returns StreamWriter A StreamWriter that writes to the specified file
using UTF-8 encoding.
Then you are not closing it. Then you are trying to access the open file by opening it again
using (var writer = new StreamWriter(file))
However, the exception you are getting is another problem again. When using StreamWriter
DirectoryNotFoundException The specified path is invalid (for example,
it is on an unmapped drive).
All the above aside, what i suggest you do is
string file = Path.Combine(Environment.CurrentDirectory, "test.txt");
Console.WriteLine(file);
//FileMode.Create will create or overwwrite the file
using (var fs = new FileStream(file,FileMode.Create))
using (var writer = new StreamWriter(fs))
{
}
Then if you still have problems, go to that directory and check if the file is there, check the permissions on the directory and file and make sure you have the appropriate access.
In short your code is suspect and you need to fix it, secondly you need to be sure what file it is your opening, thirdly, you need to check the permissions for that file and or directory

File.Delete fails silently - how to debug?

The following code fails to delete the file and prints file delete: so I know the file exists. With my app open I am able to delete the file in file explorer.
How can I debug this?
1) File permissions? My app created the file so should be able to delete? Regardless it would throw an exception and hit my catch debug message.
2) The file exists! According to the docs any other failure besides non-existence should be caught in my catch...
if (File.Exists(fn))
{
Debug.WriteLine("file delete: " + fn);
try
{
File.Delete(fn);
}
catch
{
Debug.WriteLine("Could not delete: " + fn);
}
} else {
Debug.WriteLine("File doesn't exist: "+fn);
}
The file is saved from a RichTextBox using the following code if this matters.
TextRange range;
FileStream fStream;
range = new TextRange(mNotepad.Document.ContentStart, mNotepad.Document.ContentEnd);
fStream = new FileStream(fn, FileMode.Create);
range.Save(fStream, DataFormats.XamlPackage);
fStream.Close();
Deleting a file does not provide a guarantee that the file will actually be removed from the file system. The file might have been opened by another process, which explicitly specified delete sharing. Very similar to read and write sharing. Also available in .NET, you'd pass FileShare.Delete to the FileStream constructor.
But the physical file can of course not be removed until all processes close the file. So it lingers beyond the File.Delete() call, can be seen by File.Exists() as well. Opening the file can no longer work, that will be rejected with access denied. Otherwise an excellent reason to never use File.Exists(), it has many problems.
If you want to find out what other process has the file opened then you can use a utility like SysInternals' Handle or Process Explorer. Expect to find back a program like a virus scanner or search indexer, could be anything however. Like a .NET program :)
From MSDN:
If the file to be deleted does not exist, no exception is thrown.
Make sure your path exists. I know you said you did, but check again.
Make sure you reach the actual File.Delete line
Cheers
I had the same issue before, follow the steps to see if it helps you. As silly as it may sound. Make sure no processes other than yours are making use of that file you created? Is this application multi-threaded? Do you have services running that use the file?
Make sure your not in debug mode, and do a Build - Clean
Check that the file is still at the location and copy the file path.
Put a break point right before file deletion.
Rebuild your project after you put your break-point.
Press F5 to debug and step through the code.
Check that the file path matches the one that you have.
I tried to reproduce similar situation with my own code
string fn = #"C:\Users\Public\Pictures\Sample Pictures\Desert - Copy.jpg";
//The file is locked by Image.FromFile
Image img = Image.FromFile(fn);
//If img.Dispose() here, then file is unlocked and can be deleted
if (File.Exists(fn))
{
try
{
File.Delete(fn);
Debug.WriteLine("file delete: " + fn);
}
catch
{
//Caught
Debug.WriteLine("Could not delete: " + fn);
}
}
else
{
Debug.WriteLine("File doesn't exist: " + fn);
}
I found the file is locked by Image.FromFile() and therefore Could not delete.
For the same reason, I believe your file with path fn is locked by the Filestream ftream
Can you try to do
fStream.Dispose();
before your delete process and rerun the program to see if you can delete the file? thanks. You can dispose the fstream and create a new one if needed,right?

File.Open doesn't throw IOException when File.Move does

I face weird problem with IOException on different servers. Here is my story:
I have win server (C#) that monitors folder for file changes. Also, a FTP server (WinSSHD) is pointed on same folder. When someone uploads a file WinService checks is write complete or not. If file is uploaded WinService renames it via File.Move method.
Is write complete check is made by File.Open method. Like this:
public static bool IsWriteComplete(string filePath)
{
bool isWriteComplete;
FileStream stream = null;
try
{
stream = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite|FileShare.Delete);
isWriteComplete = true;
}
catch (IOException)
{
isWriteComplete = false;
}
catch (Exception ex)
{
isWriteComplete = false;
}
finally
{
if (stream != null) { stream.Close(); }
}
return isWriteComplete;
}
For some reason on one server it works perfectly (Win2003SP2) and on another one (Win2003SP1) is not working at all. The IsWriteComplete method says True, WinServer tries to move file and dies by IOException later. I haven't found any references regarding such issue.
To fix the issue I replaced File.Open by File.Move.
Before:
stream = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite|FileShare.Delete);
After:
File.Move(filePath, filePath);
And now it works on second server (Win2003SP1) and doesn't work on first one (Win2003SP2).
Does anybody know why it works as such?
When you use File.Open you have a "race condition", even if you use FileShare.None - after you close the file, another thread/process can sneak in and lock the file (open it) before you call File.Move. This other process might not be the FTP server, but could be something you are not even aware of, such as a virus checker. Thus you should use File.Move instead of File.Open, and catch the IOException if the File.Move fails, and then retry, until it succeeds.
When you use FileShare.ReadWrite|FileShare.Delete, you allow other processes to read, write or delete the file while you're opening it. On the other side, you can open the file while others also access it. So, try FileShare.None to open the file exclusively, which should fail as long as the file is in use by the FTP server.
Also, you should use FileAccess.ReadWrite to make sure that you have full access to the file. You do not know how the FTP server locks the file, maybe it allows other processes to open the file in read-mode and declines write mode while the upload is still in process. So, FileAccess.ReadWrite is better.
MSDN reference: http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx and http://msdn.microsoft.com/en-us/library/system.io.fileaccess.aspx
About your code:
catch (IOException)
{
isWriteComplete = false;
}
catch (Exception ex)
{
isWriteComplete = false;
}
The catch block for IOException is not neccessary if you also catch Exception...
Alternatively, you can check in other way then open method.
FileInfo fileInfo = new FileInfo(filePath);
bool isNormal = ((fileInfo.Attributes & FileAttributes.Normal) == FileAttributes.Normal);
//or
bool isReadOnly = ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);
You can find the method in either way in order to understand whether file is available or not. And you can continue based upon the status.
Please let me know if you are looking for some other things.
Found the root cause of the behavior.
There was different FTP service installed: Techia. For some reason Tectia doesn't set write lock on uploading files. That's why File.Open(filePath, FileAccess.Write) doesn't throw IOException.

overwriting file with File.CreateText (C#)

I am experiencing the following problem. I am using .NET Framework 1.1 and I am trying to overwrite a file using this code:
try
{
using (StringWriter writer = new StringWriter())
{
Server.Execute(path, writer);
using (StreamWriter sr = File.CreateText(filepath + fileName))
{
sr.WriteLine(writer.ToString());
}
}
}
catch (Exception exc)
{
...
}
Sometimes it works fine, but sometimes it does not overwrite the file and no exception is thrown. Could someone tell me what the issue may be or how to handle why it doesn't overwrite the file?
Why not just:
File.WriteAllText(Path.Combine(filepath, fileName), writer.ToString())
From MSDN:
Creates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten.
Could someone tell me what the issue may be or how to handle why it
doesn't overwrite the file?
Well, to answer your actual question, File.CreateText(string file) is behaving exactly as intended. if filepath + fileName to use your example, is a file that already exists, it opens the file instead of creating it. (It does not overwrite).
You could first check to see if the file exists using File.Exists(string file) then File.Delete(string file).
If File.CreateText(string file) doesn't suit your needs, you could try a different type. Maybe FileInfo?
Microsoft Says:
Creates or opens a file for writing UTF-8 encoded text.
Source: https://msdn.microsoft.com/en-us/library/system.io.file.createtext%28v=vs.110%29.aspx
over write can also be achieved with built in file.copy method.
File.copy has overload -
File.Copy Method (Source, Destination, OverWrite)
more info on msdn
hope this helps.

Deleting a temp file that is open c#

i have written some pdf files to a temp directory and these get displayed as a thumbnail that the user can view. when i close my form i clean up all of the files in the temp directory.
If however the user has one of the thumbnails open and then closes my application - it deletes the files and then throws an exception because the pdf is open in another process and cant be cleaned up.
I guess this is a shocking programming decision by me, but i am still a novice! How should i account for this in my code?
Thanks
You can detect if the file is in use by using code similar to below, then use that to warn the user that a file can't be deleted.
Unfortunately you can't delete a file that is in use.
public static bool IsFileInUse(string pathToFile)
{
if (!System.IO.File.Exists(pathToFile))
{
// File doesn't exist, so we know it's not in use.
return false;
}
bool inUse = false;
System.IO.FileStream fs;
try
{
fs = System.IO.File.Open(pathToFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read, System.IO.FileShare.None);
fs.Close();
}
catch (System.IO.IOException ex)
{
string exMess = ex.Message;
inUse = true;
}
return inUse;
}
You should catch that exception (in catch block you can inform user to close that file or it will not be deleted), and if the temp directory is yours you can try to delete it when application starts (or when it ends again), if its windows temp directory, then it does not matter that much
Tools like File Unlocker can release a file. However I think this could make programs depending on the file crash...
Maybe you can look up how they unlock files or manage to execute the unlocker via Process.Start to unlock your file and delete it.
However if it's you blocking the file you should try and fix this in your programm. Maybe you should dispose all loaded files (filestreams etc) before trying to clean it up.

Categories

Resources