Expand paths with tilde (~) in .NET Core - c#

If I use a disk (not URL) path with ~, e.g. ~/mike/foo, then the runtime appends it to the current working directory instead of expanding it.
These don't work:
Path.GetFullPath
Path.Combine
Is there a built-in .NET Core function that would expand such a path safely, cross-platform?

My cross-platform workaround:
myPath = myPath
.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))
.Replace("//", "/");
But there are presumably edge cases (especially cross-platform), as always. So a built-in .NET Core function, if one exists, is preferable.
(Please add your answer and I'll accept it.)

Related

C# Path.Combine for virtual paths?

I have a .NET MVC application where I am building a virtual path using the below:
Path.Combine("~/Documents/", "application", "username");
The output from this is "~/Documents/application\\username". This causes an error when passed to a Telerik RadFileExplorer however if I manually build the path as "~/Documents/application/username" it works fine. The example above uses strings but the actual code is using variables.
I'd prefer not to use String.Replace if possible... Is there an alternative to Path.Combine that would produce this output? "~/Documents/application/username"
Path.Combine adds the / for you, so you don't need to add it when combining the path.
Try like this: Path.Combine("~/Documents", "application", "username");
There are a lot of alternatives for combining the a path (which is basically a string).
you can use the $ - string interpolation and put the parameters like this: $"~/{Documents}/{application}/{username}" which is more readable than replace.
edit: just saw Raziel's answer, which is probably much better/simpler..
Livio's comment is in general incorrect. That's only true if run on a Unix-based system. If run on a Windows system Path.Combine defaults to backslashes unless otherwise specified.
From the documentation of Path.Combine it only uses the forward slash if it's explicitly included in the path component. I would suggest writing a function for the latter two arguments that just appends a forward slash to the end (and maybe also ensures that there are no slashes at the beginning because that would cause them to be interpreted as absolute paths and overwrite everything before that).

Are backslashes at the end of folder paths relevant?

I am writing a program that copies all files and directories from a source location into a target location. Both locations are provided by the user.
I was just thinking about checking whether the location paths have a backslash "\" at the end, when I decided to run some tests and from what I see it doesn't matter if you tell c#
File.Copy("C:\\test", "D:\\test")`
or
File.Copy("C:\\test\\", "D:\\test\\")`
Am I wrong? Does a backslash at the end of a file path matter?
Update:
On Windows, you apparently cannot name a file and folder the same, so it won't matter there. You should still use a (back)slash for good style and cross-platform compatability. Some software or libraries might even depend on it.
Original Answer:
A folder is generally ending in \ (or /), because there might be a file with no extension, named test. For example, these two could coexist (Linux [notice the different capitalization]):
Folder: /Users/nikxda/Docouments/Test/
File: /Users/nikxda/Docouments/test
If you work case-sensitive, then you could in fact ignore it on Windows. I'd still recommend using a trailing slash, just for
Clarification (specify it is a folder)
Good style (following conventions)
Compatibility (other software, libraries, etc. might depend on it)
Cross platform (OSX, ...)
So yes, you should always use a (back)slash at the end of your path if referring to folders.
It should make no difference, because - on windows - you cannot have a folder "test" and file named "test" without extension in the same parent directory at the same time.
However, it will be much more cleaner to have a trailing backslash within your code, because this leaves no room for speculation. And it will be better for cross-plattform purposes as well.
Thinking of URIs for example, it can definitely make a difference between a trailing slash or no trailing slash, by the way.
TLDR: Use a trailing (back)slash, please :-)

I'm writing C# code that has to run on windows and linux (under mono). Easy way to handle file paths on both?

I'm writing a mod for Kerbal Space Program that logs data to a text file for use in outside tools (matlab, etc). KSP works on both Linux and Windows and I would like my mod to play nice on both. I was kind of hoping that the mono implementation on linux would just do the smart thing and translate the \'s to /'s, especially since I'm just working with Directory.GetCurrentDirectory as my base, so I don't have to worry about detecting/specifying things like c:\ vs /.
An acceptable answer (at least for now) would be a decent way to determine which platform I'm running on and just generate the strings differently (use a seperator char variable that I can set instead of slash string literals). I could look that up myself though, I'm kind of hoping there's a slick solution. I tried Googling/searching on here but nothing really stood out.
Use Path.PathSeparator. \ on Windows, / on Unix.
If you're looking to combine directory names, you can use Path.Combine.
To get the root directory (i.e. / or C:\, you can use Path.GetPathRoot(Directory.GetCurrentDirectory())).
More info in the Path docs.
Mono provides IOMap to convert pathnames, so you can use backslashes happily in your code and then use MONO_IOMAP=all mono something.exe to start your program. Mono has a page with suggestions on application portability.
Use the System.Path.* as much as you can. It will avoid you from having to do specific OS checks to determine temp dirs, app locations, data/Desktop/Doc locations...
And use Path.Combine and stay away from having to using path separators. If you are hand parsing and building paths using Path.PathSeparator, ask your why? The odds are there is a std framework method that does what you want. KISS ;-)

Different slashes in web application paths

Why if I need to check if a folder exists on the web server I need to use backslashes in the path string:
if (Directory.Exists(#"~\assets\images\gallery\thumbnails"))
while to load the image I need to use slashes?
new WebImage("~/assets/images/gallery/thumbnail/name.jpg")
What's rule behind this?
Thanks.
Directory.Exists is a check against file system, which on Windows follows Windows path specification (the link is not exactly "specification," but will do for the purpose) which has \ as directory separator. On *nix systems, however, it would take / as directory separator. Thus, one should use Path.DirectorySeparatorChar for correctness and interoperability.
WebImage takes a URL reference (~ notwithstanding) and follows RFC 1738 which defines / as segment separator.
The two, while appearing similar, are different and (mostly) unrelated concepts.
For URLs you use forward slashes. In file paths in Windows you use backslashes. The first path is to a location on the hard drive. The second path is to a URL.
I believe WebImage refers to a virtual path, as used in URLs and referred to by the browser (for example).
Directory refers to actual physical directories on the server.
Windows uses backslash for physical directories.
URL conventions use slash for virtual paths.

Default path in .NET (e.g. in Picturebox.Load())

When I run SomePicturebox.Load("Foo.bmp") and there is a Foo.bmp in the application's startup folder, it will load this image. However I have a case where the image is not loaded (when the application is started by an installer, namely).
Now I am wondering: Is there a default path that is searched by the framework when the path is not fully qualified? How can I show this path at runtime (to reveal why the image is not loaded in some cases)?
I tried looking at the Picturebox.ImageLocation property but this said just "Foo.bmp" without a path.
This is related to WinForms, .NET Framework 4.
Answers in both C# and VB.NET are very welcome.
In VB.NET
Dim directory as String = My.Application.Info.DirectoryPath
In C#
string directory = AppDomain.CurrentDomain.BaseDirectory;
I tested and AlexC was correct and I have updated this answer.
The best way to get the current value for the path is with System.IO.Directory.GetCurrentDirectory().
Rather than dealing with this ambiguity, though, it is better to make sure you fully qualify the path. To get paths on a system that can change, you should use the System.Environment.GetFolderPath call. For example, if you want the user's documents folder:
var path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
If you happen to be using an open file dialog the following is another call I often find helpful:
var fullPath = System.IO.Path.GetFullPath(selectedFile);
There are quite a few other routines in the System.IO.Path namespace that can help you with making sure that your file and path names are always fully qualified. Hope these help!
Note - My answer is in C#

Categories

Resources