Cross-platform file name handling in .NET Core

C#Linux.Net Core

C# Problem Overview


How to handle file name in System.IO classes in a cross-platform manner to make it work on Windows and Linux?

For example, I write this code that works perfectly on Windows, however it doesn't create a file on Ubuntu Linux:

var tempFilename = $@"..\Data\uploads\{filename}";
using (FileStream fs = System.IO.File.Create(tempFilename))
{
    file.CopyTo(fs);
    fs.Flush();                    
}

C# Solutions


Solution 1 - C#

You can also use Path.DirectorySeparatorChar as below:

 Console.WriteLine("..{0}Data{0}uploads{0}{{filename}}", Path.DirectorySeparatorChar);

Reference: MSDN

Solution 2 - C#

Windows using Backslash. Linux using Slash. Path.Combine set the right symbol :
Path.Combine Method - MSDN

Solution 3 - C#

Lots of good answers. I would just like to add that one can avoid having to specify the directory separator character by using Path.Combine

Example with the file relatively located at ".\..\toto\app.config":

Path.Combine("..", "toto", "app.config");

Unfortunately, Path.Combine does not resolve a relative path to an absolute Path in .Net Core. Path.GetFullPath is here for that:

Path.GetFullPath(Path.Combine("..", "toto", "app.config"))

Solution 4 - C#

You can simply use slashes. Relative paths will work identically, and absolute paths can only be relative to the root of the main drive (as absolute paths starting with "c:" are not portable)

Solution 5 - C#

The original post is over a year old but I still ran into this issue. It seems to me like the use of dots in relative paths is also an issue.

A path like

".\\input\\mydata.csv" 

worked well on windows but not on unix. When changing the dot-notation for current directory to:

Path.GetFullPath(Directory.GetCurrentDirectory())

I had more success.

Solution 6 - C#

Of course forward slashes work fine - except when they don't. It is an older problem, but certainly LoadLibrary actually bit me in this regard. Please see https://stackoverflow.com/a/34708551/1318024 which discusses this. Even though we do expect Windows to handle path separators gracefully (which we do not expect for *nix!) it is best to use the path separator appropriate for the platform.

Solution 7 - C#

I do development on windows and linux so relative path settings in json config are not always correct for the platform. Path.Combine doesn't help if you have a path separator in the config path. Using a Replace does the trick tho. Eg:

var root = "c:\\bob";
var dir = "somepath/fred";
var path = Path.Combine(root, dir);  // = c:\bob\somepath/fred

path.Replace('/', Path.DirectorySeparatorChar); // = c:\fred\somepath\fred on windows

Solution 8 - C#

There are also problem with file name cases in linux. For instance if you have file name like Index.js and used in your code like index.js vice versa, you are having a problem too

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoman KolesnikovView Question on Stackoverflow
Solution 1 - C#onemorecupofcoffeeView Answer on Stackoverflow
Solution 2 - C#user6522773View Answer on Stackoverflow
Solution 3 - C#VilmirView Answer on Stackoverflow
Solution 4 - C#Paul StelianView Answer on Stackoverflow
Solution 5 - C#user3042674View Answer on Stackoverflow
Solution 6 - C#user1318024View Answer on Stackoverflow
Solution 7 - C#JonesieView Answer on Stackoverflow
Solution 8 - C#Ozan BAYRAMView Answer on Stackoverflow