.NET has APIs for locating special folders that can be used for application and user configuration and data storage. They provide a convenient, portable way to make cross-platform applications find the appropriate folders on different operating systems. We'll look at how
Path.GetTempFileName behave on Linux.
System.Environment class has two
public static string GetFolderPath (SpecialFolder folder); public static string GetFolderPath (SpecialFolder folder, SpecialFolderOption option);
SpecialFolder is an
enum with values like
enum has three values:
DoNotVerify. These control the return value when the folder does not exist. Specifying
None causes an empty string to be returned. Specifying
Create causes the folder to be created. And
DoNotVerify causes the path to be returned even when the folder does not exist.
SpecialFolderOption are nested in the
Environment class, and to use them directly you should add a
using static System.Environment; statement to your code.
To make this API work cross-platform, .NET Core needs to map the
SpecialFolder values to some locations. For Linux, this mapping is based on file-hierarcy and basedir-spec.
|SpecialFolder||Environment Variable||Config File||Linux Default|
The table lists all the mapped values in .NET Core 2.1. Other values are not mapped and return an empty string. The returned value is determined from left to right: first checking the environment variable, then falling back to the config file, and finally falling back to a default.
Cross-platform applications should be limited to using the mapped values, or they should be able to fall back to another location when
GetFolderPath returns an empty string.
The user home folder is read from the
HOME environment variable. When that is unset, the home directory is read from the system user database. It’s safe to assume that for known users, .NET Core will be able to determine the home directory. A number of other locations are based on the user home folder. Some can be overridden using environment variables and some others by using a file at
On Windows, most of the special folders will exist by default. This may not be the case on Linux. It is the application's responsibility to create the folder when it doesn't exist. This may require some changes to your code to use the overload with a
For example, the following code ensures the
LocalApplicationData folder will be created if it doesn’t exist.
// Use DoNotVerify in case LocalApplicationData doesn’t exist. string appData = Path.Combine(Environment.GetFolderPath(SpecialFolder.LocalApplicationData, SpecialFolderOption.DoNotVerify), "myapp"); // Ensure the directory and all its parents exist. Directory.CreateDirectory(appData);
Path.GetTempPath and Temp.GetTempFileName
System.IO.Path class has a method that returns the path of the current user's temporary folder:
public static string GetTempPath ();
Windows applications may assume the path returned here is user-specific. This is because the implementation picks up the
USERPROFILE environment variable. When the variable is unset, the API returns the Windows temp folder.
On Linux, the implementation returns
/tmp. This folder is shared with other users. As a consequence, applications should use unique names to avoid conflicts with other applications. Furthermore, because the location is shared, other users will be able to read the files created here, so you should not store sensitive data in this folder. The first user to create a file or directory will own it. This can cause your application to fail when trying to create a file or directory that is already owned by another user.
Temp.GetTempFileName method solves these issues for creating files. It creates a unique file under
GetTempPath that is only readable and writable by the current user.
On Windows, the value returned by
GetTempPath can be controlled using the
TEMP environment variables. On Linux, this can be done using
On systems with
systemd, like Fedora and Red Hat Enterprise Linux (RHEL), a user-private temporary directory is available and can be located using the
XDG_RUNTIME_DIR environment variable.
In this article, you’ve seen the features and limitations of using
Temp.GetTempFileName in your cross-platform .NET Core applications.
Here are some additional .NET Core articles that might be helpful:
- Improving .NET Core Kestrel performance using a Linux-specific transport
- Using OpenShift to deploy .NET Core applications
- Running Microsoft SQL Server on Red Hat OpenShift
- Securing .NET Core on OpenShift using HTTPS
- Announcing .NET Core 2.1 for Red Hat Platforms
Last updated: September 3, 2019