File not found Exception.. But it's there - c#

Hey this is going to be one of those dumb questions. I am trying to pick up a file on my local system and I keep getting a FileNotFoundException thrown.
Someone set me straight please :)
if( File.Exists(#"C:\logs\hw-healthways-prod_2009-08-26.tar"))
{
Console.WriteLine("Yay");
}
else
{
throw new FileNotFoundException();
}
Tried moving the file into the same location as the executing application and did the following:
if( File.Exists("hw-healthways-prod_2009-08-26.tar"))
Same thing.
Then I made a random txt file and parked it there too.. "me.txt"
And it works?! So you thing the file name is the problem?

Try doing Directory.GetFiles(#"C:\logs"). It's possible that the file in question has odd characters that are getting interpreted one way by Windows Explorer (presumably where you're reading "the file's property" from?) but a different way by the .NET Framework. This can happen if you have UTF-8 characters in the filename (perhaps an en dash?).

May be the name of the file is "hw-healthways-prod_2009-08-26.tar.tar" instead of "hw-healthways-prod_2009-08-26.tar", I had this problem because by default the extension files are hidden on windows

You may want to check your file permissions. Your computer may not have permission to the file.

C:\logs\hw-healthways-prod_2009-08-26.tar should be C:\\logs\\hw-healthways-prod_2009-08-26.tar. \ means the next character is an escape character.

Related

In C# I get a System.IO.DirectoryNotFoundException only for specific file path

I have the following code in C#:
FileInfo file = new System.IO.FileInfo(filePathAndName);
file.Directory.Create();
File.WriteAllText(filePathAndName, headers + singleOption.Value);
When the file name is
D:\Option Data\DiscountOptionData\Single Option Files\NUL\NUL2008-09-20p32.50.csv
then it throws a System.IO.DirectoryNotFoundException. In fact, any with NUL in them throw the exception.
But any other file names I'm using, such as
D:\Option Data\DiscountOptionData\Single Option Files\NSI\NSI2006-06-17c50.002006-02-09.csv
do not throw exceptions.
The relevant parts of the filename are read from an excel file. I've tried using LEN([Cell]) on them and can't find any hidden characters.
You probably shouldn't use nul (or con or prn) for file names, since these are considered special devices by windows. You can see this if you open up a cmd window and enter type nul:
c:\pax> type nul
c:\pax> type nulx
The system cannot find the file specified.
In fact, it even misbehaves with an extension. I once had a source file const.h which I renamed to con.h and then spent a bit of time wondering why my code wasn't compiling. Turns out, because I'd used #include "con.h", Windows had
helpfully opened up the console device to read my header file.
In other words, it was waiting for me to type it in :-)
If you must have a directory hierarchy where NUL*.csv files are stored, one solution is to use a prefix to ensure special device names don't appear, something like:
D:\OptnData\DscntOptnData\SnglOptnFls\dirNUL\NUL2008-09-20p32.50.csv
^^^^^^
This bit

Why is Visual Studio saying my file doesn't exist when it evidently does? Also, does it matter that it's adding a forward slash?

I have verified multiple times that the file exists, and when I copy-and-paste the path to the file from the code into Windows explorer, it works. It takes me to the file. So please help, what is going on? The exception message, for your reference says
System.IO.FileNotFoundException: Could not find file "/C:\Users\Daniel\Desktop\Couryah\products_export.csv
Why is this forward slash in front of it? Is it the culprit? How do I fix it?
public void PopulateList()
{
string line;
System.IO.StreamReader file = new System.IO.StreamReader("C:\\Users\\Daniel\\Desktop\\Couryah\\products_export.csv");
while ((line = file.ReadLine()) != null)
{
Product newProduct = new Product();
newProduct.setAll(line.Split(',')[1], line.Split(',')[3], Convert.ToDouble(line.Split(',')[19].Replace("$", "")), line.Split(',')[24]);
productList.Add(newProduct);
}
}
I would pre-check to make sure the file exists. Put into a variable just to be sure no false/bogus value with bad forward slash. Then, check to see if the file exists or not to confirm BEFORE opening.
Next, instead of stream, I just changed to a File.ReadAllLines() which reads each line at a time into an array.
public void PopulateList()
{
var whatFile = "C:\\Users\\Daniel\\Desktop\\Couryah\\products_export.csv";
if ( ! System.IO.File.Exists( whatFile ))
{
MessageBox.Show("No such file: " + whatFile);
return;
}
foreach( var line in System.IO.File.ReadAllLines( whatFile ))
{
Product newProduct = new Product();
newProduct.setAll(line.Split(',')[1], line.Split(',')[3], Convert.ToDouble(line.Split(',')[19].Replace("$", "")), line.Split(',')[24]);
productList.Add(newProduct);
}
}
Now, this does not necessarily answer why a file does not exist, but here is one thing I specifically ran into and was scratching the heck out of my head. I had a similar for a client. I had a file on the desktop that was a csv, but no matter what, had same issue.
What I actually had found is the file "MyFile.csv" was ACTUALLY a "MyFile.csv.txt". Wondering what the... Ended up going to a DOS command prompt, changed to folder and did a DIR of that folder to see it.
Come to find, Windows likes to default HIDING FILE NAME SUFFIX of common file extensions. So, even though the desktop had .csv, because the .txt was hidden was causing the not found file. To confirm, I changed the file manager to NOT HIDE file name suffix. Sure enough, stripped the .txt and everything worked.
Not saying this is what you have, but sometimes the obvious isn't.
One more note. I would put a breakpoint in your debugger to stop at the point of checking the file. Then use your watch window and see what variables are and also check/change as needed to confirm its doing what you thought it should.
One additional option...
Try using what WINDOWS thinks is your desktop.
var whatFile2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Couryah\\products_export.csv")
How does THIS "SpecialFolder.Desktop" compare with your C:\users...

Xamarin Android throws IOException when using ZipFile.ExtractToDirectory method

I try to use the following code in my project without any success and it's driving me mad.
System.IO.Compression.ZipFile.ExtractToDirectory(filePath, appPath);
The parameters are:
filePath = "/storage/emulated/0/Flashback_Backup/memory_backup.zip"
appPath = "/storage/emulated/0/Flashback"
According to the documentation here IOException should be thrown if:
The directory specified by destinationDirectoryName already exists.
-or- The name of an entry in the archive is Empty, contains only white space, or contains at least one invalid character.
-or- Extracting an archive entry would create a file that is outside the directory specified by destinationDirectoryName. (For example,
this might happen if the entry name contains parent directory
accessors.)
-or- An archive entry to extract has the same name as an entry that has already been extracted from the same archive.
As far as I know none of it applies. The zip file is a totally valid one, which I compressed with the Directory.CreateDirectory method, and only contains a few uniquely named JSON files. I tried with and without existing "Flashback" folder too, but nothing seems to work.
If anyone have any ideas or solutions please tell me because I'm seriously lost at this. I can provide more info if needed.
Try to wrap extraction intro try-catch, it may give you a better understanding of what is going on.
try {
System.IO.Compression.ZipFile.ExtractToDirectory(filePath, appPath);
} catch (Exception ex) {
Console.Log(ex);
}
If there is an error, it will be one of your listed above.

File Copy - Keep both files if name conflicts

File.Copy allows simple file copying. When a duplicate file name is encountered, File.Copy has a third parameter to determine if the original file is overwritten or not.
Is there a built-in .Net function that allows a third option to rename the copied file and hence keep both files?. For example, the file copy would automatically rename "readme.txt" to "readme - Copy.txt" if another readme.txt already existed in the destination folder - similar to Windows Explorer functionality?
I realize it can be written but didn't want reinvent the wheel if it exists.
Thanks in advance.
Nope, this functionality doesn't exist out of the box (thankfully, as it would introduce a responsibility to the framework which it ought not to have*,) so if you want this, then you will need to implement a bespoke solution.
*Which implementation should it take? Appending "- Copy", appending "(n)"? It becomes problematic rather sherpish.
There's nothing you can do all-in-one go with File.Copy, however you could test if the destination exists and then Move instead.
Move takes two parameters, and you can essentially rename at the same time.
if File.Exists(destinationPath) {
File.Move(source, destinationPathRenamed);
} else {
try {
File.Copy(source, destinationPath);
} catch (IOException ex) {
// destinationPath file already exists
File.Move(source, destinationPathRenamed);
}
}
See Move documentation
EDIT:
Updated code above. #xanatos makes a good point about atomic operation. I made no assumptions about whether there are other processes accessing the file(s).
Note that I haven't added other error handling for the source file being deleted before the operation begins either.
var destinationPath = c:\temp\archive.txt;
if(File.Exists(destinationPath))
destinationPath = string.Format("c:\temp\archive.{0}.txt", DateTime.Now.ToString("yyyyMMddHHmmffff"));
File.Move(filePath, destinationPath );

UnauthorizedAccessException on newly created files

I have an application that is looking through some files for old data. In order to make sure we don't corrupt good projects, I'm copying the files to a temporary location. Some of the directories I'm checking are source-code directories, and they have .svn folders. We use Subversion to manage our code.
Once I've searched through all of the files, I want to delete the temp cache. Sounds easy, right?
For some reason, all of my .svn directories won't delete from the cache. They crash the app.
For reasons (too deep to go into here), I have to use the temp folder, so just "scan the original file" is out of the question for political reasons.
I can go into explorer and delete them. No problem. No warnings. Just deletes. But the code crashes with "Access to {file} is denied." I'm at my wits end with this one, so any help would be appreciated.
While I've simplified the function a LITTLE for sake of your sanity, the code REALLY is about this simple.
List<string> tmpCacheManifest = new List<string>();
string oldRootPath = "C:\\some\\known\\directory\\";
string tempPath = "C:\\temp\\cache\\";
foreach (string file in ListOfFilesToScan)
{
string newFile = file.Replace(oldRootPath, tempPath);
// This works just fine.
File.Copy(file, newFile);
tmpCacheManifest.add(newFile);
}
// ... do some stuff to the cache to verify what I need.
// Okay.. I'm done.. Delete the cache.
foreach (string file in tmpCacheManifest)
{
// CRASH!
File.Delete(file);
}
* Update *: The exception is UnauthorizedAccessException. The text is "Access to the path 'C:\temp\cache\some-sub-dirs\.svn\entries' is denied."
It happens under XP, XP-Pro and Windows 7.
* Update 2 * None of my validation even ATTEMPTS to look at subversion files. I do need them, however. That's part of the political crap. I have to show that EVERY file was copied... wheter it was scanned or not.
And I realize what the usual suspects are for File.Delete. I realize what UnauthorizedAccessException means. I don't have access. That's a no-brainer. But I just copied the file. How can I NOT have access to the file?
* Update 3 *
The answer was in the "read-only" flag. Here's the code I used to fix it:
foreach (string file in ListOfFilesToScan)
{
string newFile = file.Replace(oldRootPath, tempPath);
// This works just fine.
File.Copy(file, newFile);
//// NEW CODE ////
// Clear any "Read-Only" flags
FileInfo fi3 = new FileInfo(fn);
if ((fi3.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
fi3.Attributes = (FileAttributes)(Convert.ToInt32(fi3.Attributes) - Convert.ToInt32(FileAttributes.ReadOnly));
}
tmpCacheManifest.add(newFile);
}
// ... do some stuff to the cache to verify what I need.
As far as I recall, Subversion marks the files in its .svn subdirectories as read-only.
Try resetting the read-only attribute before deleting the file. I don't really know any C#, but a quick Google suggests this might do the trick:
File.SetAttributes(file, FileAttributes.Normal);
The only problem I see would be in this part:
// ... do some stuff to the cache to verify what I need.
If you do open the file and forget to close it, you still have exclusive access to it, and thus can't delete it later on.
Sounds like you don't have access to delete the file...
system.io.file.delete
The above link says you get UnauthorizedAccessException when:
The caller does not have the required permission.
-or-
path is a directory.
-or-
path specified a read-only file.
It's one of those.
Sounds like a permissions issue. Tricky one though as you obviously have write access if the File.Copy already works....
Only thing I could think of is the file still has a handle opened somewhere (as others have suggested perhaps in your do some stuff to the cache part).
First of all: "Crash" means an exception, right? Which one? Can you catch it and show it?
Second thing: You are copying subversion repositories, although you don't care about the subversion metadata? That's what svn export is about (no .svn directory in the target).
The answer to the first question is what you really need to provide. Maybe something grabs the .svn and locks some files. TortoiseSVN maybe (to give you nice overlay icons..)?
If a folder contains read only files, Directory.Delete won't delete it and raise the exception you're getting. For future visitors of this page, I've found a simple solution which doesn't require us to recurse through all the files and changing their read-only attribute:
Process.Start("cmd.exe", "/c " + #"rmdir /s/q C:\Test\TestDirectoryContainingReadOnlyFiles");
(Change a bit to not to fire a cmd window momentarily, which is available all over the internet)
Not understanding what you want to do so much, but what about chmoding it to 777 or 775. :-/
Edit:
Noticed your on windows. You'd have to change the permissions. Don't know how windows does that :-/

Categories