Best practice for building file paths in C# - c#

I'm working on a C# project where I must build paths to various files and folders. These are all under one root folder which I have specified in my Web.config file.
For example:
"start with: "D:\builds\" from my Web.config
Pass to GetRelativePath() to get "D:\builds\5.2\5.2.9751"
Then pass to GetAutoSuitePath() to get "D:\builds\5.2\5.2.9751\AutoSuite\"
Then pass to ParseBrLog which will read "D:\builds\5.2\5.2.9751\AutoSuite\AASanity.csv"
My paths are correct, but I just want to know what the best practice is for incomplete paths. Should I add a "\" to the end of every folder ("D:\Builds\5.2\" + "test.txt"), or add one to the start of every folder/file I add to the path ("D:\Builds" + "\5.2" + "\test.txt")? Currently, I'm, doing it both ways, and want to choose one uniform way of doing it.

Use the Path class to build up your paths. It will do the right thing.
Performs operations on String instances that contain file or directory path information. These operations are performed in a cross-platform manner.
var full = Path.Combine(baseDir, dirFragment);

Use Path.Combine to concatenate path tokens.
If the path is a file to set/change the extension use Path.ChangeExtension.

Related

File read/write paradigms on Unity- which to use?

I want to load some JSON files that are stored in my assets.
I don't know where I'm supposed to store them in the assets. Should I store it in the "Resources" folder, in the "StreamingAssets" folder or somewhere else ?
I don't know what path I'm supposed to use. I heard you need to write : path = "jar:file://" + Application.dataPath + "!/assets/"; for the StreamingAssets but there is also Application.streamingAssetsPath. I also heard you always need to use Application.persistantDataPath. So which path should I use ?
I don't know what I can use in to access the files in C#. I've heard you can use Directory.Exists() and File.Exists() but if you use the StreamingAssets you must use WWW. Is that right?
You can get a basic idea in this answer.
In addition, I would suggest placing anything you want to package with your game in your Resources folder, which you can access by using Resources.Load(). You can iterate through these directories however you want- ex: Resources.Load("folder/file");.
If you want to write files, they have to go in Application.persistentDataPath as that's the only write-able directory (that's specified by Unity), i.e. for run-time files only. But once a file is stored there, it is persistent between sessions.
You can, of course, specify absolute paths and try to load assets from there, but that's more risk than necessary (paths differ on different devices).
You could ignore Application.dataPath altogether, until you find a specific need for it (ex: to access files that are not in persistentDataPath, but not in resources either).
I hope that helps!

Get a file path C#

I have a .txt file that I need to read in my program. For the moment I have the directory hardcoded as such:
file = new StreamReader(#"C:\Users\<username>\Documents\File.txt");
However that will (obviously) not work on any other PC that does not have that access to altering the code, or (by some strange happenstance) the same directory as the original code.
How can I get the full file path to set it in my program using C#?
You could create the file in their Application Data directory (they could still find it if they wanted to, but at least it wouldn't be as obvious as the My Documents folder).
When you want to access it, use the Environment class. There are methods for locating special folders for the current user, without resorting to hard-coded paths:
var filePath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData), "File.txt");
Option 1:
Application.StartupPath can be used for the purpose.
It gets the path for the executable file that started the application, not including the executable name.
Keep File.txt with your executable.
Option 2:
Use Environment.SpecialFolder.ApplicationData
It gives directory that serves as a common repository for application-specific data for the current roaming user.
NOTE: If you want to restrict the user to look into the contents of File.txt then you might need to encrypt the contents.

Using WritePrivateProfileString to write path issue

I am using WritePrivateProfileString in c# (through DllImport) to store paths taken from textboxes on the interface. And the .ini file name is hardcoded in my application
string ini_file = ".\\config.ini";
However, when the file writing happens, the configuration file is written to the first path taken from the interface instead of writing it to the exe directory. Which is quite odd.
Debugging shows that the values are sent correctly to the WritePrivateProfileString but it still is written to the wrong location. Anyone knows why is that happenening?
I'd guess that something is changing the working directory of your process, most likely your code in the process. Note that the documentation has this to say:
If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.
Now my guess is that this applies if you supply just a file name. Because your file name starts with . I believe that will force the function to start from the current working directory.
Having said all of that, and no matter what the cause of the problem is, you should use a fully-qualified path in order to make sure the file is written where you want it to be written. Whenever you want the file to go in a specific directory, it's always easiest to force that by using fully-qualified paths.
You can find the path to your executable using Application.ExecutablePath and then remove the file name part.
Another point to make is that the same directory as the executable may be a bad choice. If your program is installed under the Program Files directory then the directory which contains the executable will not be generally writeable. I think you should consider using a directory under in the user profile. Look for one of the Environment.SpecialFolder values.
Further to David Heffernan's answer - you can use
Path.GetDirectoryName(Application.ExecutablePath);
to safely get just the running application's folder part.
If you're in a dll rather than an executable, you can use
Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);
Both require System.IO, and were originally posted here. Second example also requires System.Reflection).
Application data files are supposed to be written to the LocalApplicationData special folder.
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
You typically will not have permissions to write into the Program Files folder etc.

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.

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).

Categories