Checking the existence of a file using relative path - c#

What is the best way to check the existence of a file using relative path.
I've used the following method but it returns false despite the fact that file is existing.
bool a = File.Exists("/images/Customswipe_a.png");

That's not a relative path. You need to leave off the first / otherwise it will be interpreted as being rooted (i.e. C:/images...)

I guess that you are running this code in asp.net application, thats why you get false.
In asp.net you should use Server.MapPath("/images/Customswipe_a.png") to get "correct" path (relative to the web application root directory). Otherwise you get path local to the webserver executable (IIS/WEBDAV/..name any other).

The relative path is relative to the current working directory. It may not be the application directory. Call GetCurrentDirectory() to check the actual path you are testing.

You just need to define what your file is relative to
Your application main assembly?
Current directory?
Application data directory?
name it...
In each of these cases I'd suggest you to convert it into an absolute path by Path.Combine method:
public static readonly string AppRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
...
//calling with a '/' heading makes the path absolute so I removed it
var fullPath = Path.Combine(AppRoot, "images/Customswipe_a.png");
var exists = File.Exists(fullPath);
This way you can guarantee where you are looking for. Even the Open/Save file dialogs may change your current directory. So, calling File.Exists without full path is usually a wrong decision.

You can test this path with System.IO.DirectoryInfo:
DirectoryInfo info = new DirectoryInfo("/images/Customswipe_a.png");
string absoluteFullPath = info.FullName;
As Mike Park correctly answered this path is likely to be (i.e. C:/images...)

The relative path, is a relative to something.
In this API, it will, according to the documentation File.Exists:
Relative path information is interpreted as relative to the current
working directory.
So everything here is depends what is CurrentDirectoty at the moment of execution of this query.
Plus, your path is not valid Desktop path (I assume you pick it from some web file, or knowledge). To understand if specified path contains not valid characters use GetInvalidCharacters function.
In your specific case it would be enough to use #"\images\Customswipe_a.png".

The path is relative to the location of your binary file. In the case of a visual studio project, this would be %PROJECTDIR%/bin/(RELEASE||DEBUG)/
What I would do is put the filesystem root in a config file, and use that for your relative path.

In a WinForms application you can get the directory of the exe file with
string directory =
Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
Another solution uses Reflection
string directory =
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

As of .NET Core 3.1, this works:
Use dependency injection to include service IWebHostEnvironment
private IWebHostEnvironment Env;
public MyController (IWebHostEnvironment env){
Env = env;
}
Then use it to get path to root of app with Env.ContentRootPath
And combine it all:
var file = System.IO.Path.Combine(Env.ContentRootPath, "images", "some-file.png");

Related

How to get current windows directory e.g. C:\ in C#

As the title suggests, how can you get the current OS drive, so you could add it in a string e.g.:
MessageBox.Show(C:\ + "My Documents");
Thanks
Add a reference to System.IO:
using System.IO;
Then in your code, write:
string path = Path.GetPathRoot(Environment.SystemDirectory);
Let's try it out by showing a message box.
MessageBox.Show($"Windows is installed to Drive {path}");
When looking for a specific folder (such as My Documents), do not use a hard-coded path. Paths can change from version-to-version of Windows (C:\Documents and Settings\ vs C:\Users\) and were localized in older versions (C:\Users\user\Documents\ vs C:\Usuarios\user\Documentos\). Depending on configuration, user profiles could be on a different drive than Windows. Windows might not be installed where you expect it (it doesn't have to be in \Windows\). There's probably other cases I'm not aware of.
Instead, use the Shell API (SHGetKnownFolderPath) to get the actual path. In .NET, these values are easily obtained from Environment.GetFolderPath. If you're looking for the user's My Documents folder:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Full list of special folders
You can use Environment.CurrentDirectory to get the current directory. Environment.SystemDirectory will give you the system folder (ie: C:\Windows\System32). Path.GetPathRoot will give you the root of the path:
var rootOfCurrentPath = Path.GetPathRoot(Environment.CurrentDirectory);
var driveWhereWindowsIsInstalled = Path.GetPathRoot(Environment.SystemDirectory);
If you don't mind a little parsing: Environment.SystemDirectory returns the current directory.

Relative path to a file using C#

I have a command-line program that takes a configuration file as a parameter, that is, C:\myprogram.exe -c C:\configFiles\MyConfigFile.txt. I want to be able to make it so that I do not have to type the absolute path to the configuration file, so instead of the above I can just enter C:\myprogram.exe -c MyConfigFile.txt
I'm not familiar enough with how C# deals with paths to understand if or how this can be done. Any insight is appreciated.
Use Path.GetFullPath()
Something like:
string path = "MyConfigFile.txt";
string fullPath = System.IO.Path.GetFullPath(path);
That's if the config file is in the current directory. If they're stored in a standard folder you can use Path.Combine()
string basePath = "C:\Configs";
string file = "MyConfigFile.txt";
string fullPath = System.IO.Path.Combine(basePath, file);
You are only passing in a string. It is up to you to handle it in a relative path way.
If you used this code, it would by default support relative paths.
FileInfo will attempt to use the path in Environment.CurrentDirectory first, if the path provided is not explicit.
var file = new FileInfo(args[1]); // args[1] can be a filename of a local file
Console.WriteLine(file.FullName); // Would show the full path to the file
You have some general options:
Store the directory path in the config file (you said you don't want to do this)
Have the user enter a relative path (....\MyFile.txt)
Programmatically search for files matching the name (very slow and prone to locating multiple files of the same name)
Assume the data file is in the executing directory
Any way you slice it, the user must indicate the path to the directory, be it in the config file, entering relative path, or selecting from a list of files with identical names found in different directories.
ANALOGY: You place a textbook in a locker, somewhere in a school. You ask your friend to get the book from "a locker", without hinting as to exactly which locker that may be. You should expect to wait a very long time and end up with 50 similar books. Or, provide a clue as to the hallway, bank of lockers, and/or locker number in which the book may be stored. The vagueness of your clue is directly correlated with the response time and potential for returning multiple possibilities.
Without the relative path as part of the input argument, your application would need to:
either search for the file that is passed in
append the path name of the Config directory to the filename
Well, standard .NET classes are working with relative paths in same way as with absolute, so, you could use them without any problems. If C: root is working directory of your program, you could use c:\myprogram.exe -c configFiles\MyConfigFile.txt and it will point to c:\configFiles\MyConfigFile.txt.

full path of a folder in c#

i need to get the full folder path in a windows project using c#.I tried with path.getFulPath(filename).bt it returns the application path+filename.how can i get the actual path like "D:\eclipse_files\ads_data"?
A relative path such as myfile.txt is always resolved in relation to the current working directory.
In your case the current working directory seems to be D:\eclipse_files\ads_data so your relative file path gets resolved to D:\eclipse_files\ads_data\myfile.txt when you call Path.GetFullPath.
To solve the problem, either make sure that you start with an absolute path from the beginning, or, that your working directory is set correctly.
You can get/set the working directory using the Directory.GetCurrentDirectory and Directory.SetCurrentDirectory methods.
Your question is not very clear, but I think you're looking for this:
string path = Path.GetDirectoryName(filename);
If I have understood correctly, you have a filename, for example 'doc.txt', and you want to have a method to return the full path of this file regardless of where the application runs from?
If this is what you ask it is not possible. Have you considered that there might be several files called 'doc.txt' on your harddrives?
The best you can hope to do it to search all harddrives, and return a list of all files found with the same name, but that will just be ridicously slow.

How to determine a full path of a named folder?

I want to determine the full path of certain folders. In my array, I just have the names of the folders, but when my application will get installed on another user's machine, my program must be able to determine the full-path of these folders.
How to get the fullpath?
You can check the method Path.GetFullPath, it could be useful to what you're trying to do.
Path.GetFullPath Method
Did you mean the My Documents folder and the rest? It's not obvious for me from your question.
The My Documents folder is:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
And the rest of the special system folders can be retrieved in a similar way.
By prefixing it with another Path. Which Path depends on your application.
string path = ...
string fullPath = System.IO.Path.Combine(path, folderNames[i]);
You could take a look at Environment.GetFolderPath(...)
Sounds to me that you mean actually the current path plus an additional path. I.e., suppose your application is installed in c:\installations and you need the relative path of resource\en-US, you want to find c:\installations\resource\en-US.
Normally I would go for getting the current path, but in Windows it is possible to start an application as if it is executing from a different path. A fool-proof way of getting the path of the current application (where it is installed) is as follows:
// gets the path of the current executing executable: your program
string path = Assembly.GetExecutingAssembly().Location;
// transform it into a real path...
FileInfo info = new FileInfo(path);
// ...to make it easier to retrieve the directory part
string currentPath = info.Directory.FullName;
Now it becomes trivial to get new paths.
string someRelativePath = #"reource\en-US";
string someFullPath = Path.Combine(currentPath, someRelativePath);
I know, it looks a bit contrived, but it is safer then using the current path.
FileInfo.FullName, if you are lucky and the constructor finds your file somehow (e.g. current working directory).

ASP.NET Relative Paths in Referenced Libraries

I have an ASP.NET website in which I am loading some validation rules from an xml file. This xml file name, with no path info, is hard coded in a library. (I know that the hard coded name is not good, but let's just go with it for this example).
When I run the website, ASP.NET tries to find the xml file in the source path, where the C# file in which name is hard coded is. This is completely mind boggling to me, as I can't fathom how, at runtime, we are even considering a source path as a possibility for resolving an unqualified filename.
// the config class, in C:\temp\Project.Core\Config.cs
public static string ValidationRulesFile {
get { return m_validationRulesFile; }
} private static string m_validationRulesFile = "validation_rules.xml";
// using the file name
m_validationRules.LoadRulesFromXml( Config.ValidationRulesFile, "Call" );
Here is the exception showing the path we are looking in is the same as Config.cs:
Exception Details: System.IO.FileNotFoundException:
Could not find file 'C:\temp\Project.Core\validation_rules.xml'.
Can anyone explain this to me? I already know how you are supposed to handle paths in general in ASP.NET so please don't respond with solutions. I just really want to understand this, since it really surprised me, and It is going to bother me to no end.
UPDATE
Here is the relevant code for LoadRulesFromXml
public void LoadRulesFromXml( string in_xmlFileName, string in_type )
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load( in_xmlFileName );
...
UPDATE2
It looks like the Cassini web server gets its current directory set by VS, and indeed it is set to the path of my library project. I'm not sure exactly how VS determines which project to use for the path, but this at least explains what is happening. Thanks Joe.
If you don't supply a path, then file access will normally use the current working directory as the default. In ASP.NET this is probably your web application directory.
It's not usually a good idea to rely on the current working directory, so you can use Path.Combine to specify a different default directory, e.g. one relative to AppDomain.CurrentDomain.BaseDirectory, which is also the web application directory for an ASP.NET app.
You should add the path explicitly to the name of the file you're opening. You could also try tracing the current working directory.
When running Cassini from Visual Studio, the current directory is inherited from whatever happens to be Visual Studio's working directory: this seems to be your case.
I.e.:
public void LoadRulesFromXml( string in_xmlFileName, string in_type )
{
// To see what's going on
Debug.WriteLine("Current directory is " +
System.Environment.CurrentDirectory);
XmlDocument xmlDoc = new XmlDocument();
// Use an explicit path
xmlDoc.Load(
System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
in_xmlFileName)
);
...
At a complete guess I would say that the Method LoadRulesFromXml() is looking at the path of the Application Root URL for where the site is hosted... which is C:\temp\Project.Core\
probably by doing a Server.MapPath("~")
Can you post the code for LoadRulesFromXML or do you have that code ?

Categories