-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proposal: Create a Temporary Directory class in System.IO #2048
Comments
This would be extremely useful, especially if has an overload to create a temp file in any directory, as suggested by @danmoseley in #40414 (comment)
|
Just clarifying the quote above was from Java. To make progress here, someone needs to create a formal API proposal (whether it be a type or just new methods) using the standard format. It can be pasted here. Then we can all discuss shape/behavior. |
/cc @carlossanlop
Design considerations:For 1. We need to create a subdirectory in common temporary directory with the application name (as default) and unique session number. runtime/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CodeCompiler.cs Lines 185 to 191 in ebba451
For 3. There are a lot of options for Stream class. We could implement common case with strongly locked temp file and define a delegate for other scenarios. See follow TempFileCollection use case: runtime/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/Executor.cs Lines 50 to 54 in ebba451
runtime/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/Executor.cs Lines 15 to 16 in ebba451
For 4. It is out of my design since I believe it is better implement by OS means.
ProposalImplementation main...iSazonov:tempdir namespace System.IO
{
public sealed class TemporaryDirectory : IDisposable
{
public TemporaryDirectory() { }
public TemporaryDirectory(string tempDir) { }
public TemporaryDirectory(bool keepFiles) { }
public TemporaryDirectory(string tempDir, bool storeFileNames) { }
void System.IDisposable.Dispose() { }
public void Dispose(bool disposing) { }
~TemporaryDirectory() { }
public static string TemporaryDirectoryPrefix { get { throw null; } set { } }
public static FileStream CreateTempFileStream(bool keepFile = false) { throw null; }
public static FileStream CreateTempFileStream(string fileExtension, bool keepFile = false) { throw null; }
public static FileStream CreateTempFileStream(CreateTempFileStreamFunc func, bool keepFile = false) { throw null; }
public static FileStream CreateTempFileStream(CreateTempFileStreamFunc func, string fileExtension, bool keepFile = false) { throw null; }
public delegate FileStream CreateTempFileStreamFunc(string fileName, bool keepFile);
public FileStream GetTempFileNameStream() { throw null; }
public FileStream GetTempFileNameStream(bool keepFile) { throw null; }
public FileStream GetTempFileNameStream(string fileExtension) { throw null; }
public FileStream GetTempFileNameStream(string fileExtension, bool keepFile) { throw null; }
public FileStream GetTempFileNameStream(CreateTempFileStreamFunc func) { throw null; }
public FileStream GetTempFileNameStream(CreateTempFileStreamFunc func, bool keepFile) { throw null; }
public FileStream GetTempFileNameStream(CreateTempFileStreamFunc func, string fileExtension) { throw null; }
public FileStream GetTempFileNameStream(CreateTempFileStreamFunc func, string fileExtension, bool keepFile) { throw null; }
public string GetTempFileName() { throw null; }
public string GetTempFileName(bool storeFileName) { throw null; }
public string GetTempFileName(string fileExtension) { throw null; }
public string GetTempFileName(string fileExtension, bool storeFileName) { throw null; }
public string BaseTemporaryDirectory { get { throw null; } }
public bool StoreFileNames { get { throw null; } }
public void Clear() { }
public IReadOnlyList<string> FileNameList { get { throw null; } }
}
} |
The proposed implementation by @iSazonov looks great! |
The simplest API is a counterpart to public static class Path
{
/// <summary>
/// Creates a uniquely named, empty directory on disk and returns the full path of that directory.
/// </summary>
public static string GetTempDirectoryName();
} Maybe we can start with that? The proposed On Unix, like mkdtemp, the directory should be created with permissions |
It was. It was deemed not as useful as addressing more real-world scenarios, which was done. Several issues have been closed in favor of that. |
@iSazonov is your point that it is not solving all use-cases? or that it is too low level? |
@tmds I think no needs to have just another low level API because we already have GetTempFileName() and GetTempPath(). Using the API developers can implement any scenario. |
Using these APIs it's not possible to set the mode to The File APIs have several ways to do the same thing. The So I think it's useful to have: public static class Path
{
/// <summary>
/// Creates a uniquely named, empty directory on disk and returns the full path of that directory.
/// </summary>
public static string GetTempDirectoryName();
} API feedback for
public static class File
{
public static FileStream OpenTempFile(string directory, string extension = "tmp", FileMode mode = FileMode.CreateNew, FileAccess access = FileAccess.Write, FileShare share = FileShare.None, int bufferSize = 4096, FileOptions options= FileOptions.None);
} |
GetTempFileName() does this for you on Unix. GetTempPath() returns that OS defines and users should care about security - this is why the API proposal was created: introduce new safe API for common scenarios.
You can reopen #31243. But before ask yourself that scenarios you want address and aren't all of these scenarios covered by the API proposal. |
Yes, for files. There is no API for directories.
I think it is meaningful to have a method next to @JeremyKuhne should weigh in here, since he closed #31243. |
To approve the API we need know scenarios the API covers. Nobody needs a temporary directory per se. The next step after creating temp directory will always be to create a temporary file or files - TemporaryDirectory class covers a lot of similar scenarios. |
It can also be non-temporary files in a directory that happens to be temporary. The files don't need to know, so they don't need to be created using |
Non-temporary files in a temp directory? This seems absurd. Can you specify a real project on GitHub where this is used?
|
I mean: if the responsibility to delete the files lies with the temporary directory, there is nothing special about the files.
The naming fails here. The referenced |
I'm not fundamentally opposed to it. Note, however, that I no longer am working on System.IO. |
Temporary means two different things:
I think we should keep these separate. APIs for deleting using // Deletes files and directories on Dispose.
sealed class TemporaryFileCollection : IDisposable
{
public TempFileCollection();
public void AddFile(string path);
public void AddDirectory(string path);
public void DeleteAll(); // throws AggregateException
public bool TryDeleteAll();
public void Dispose() => TryDeleteAll();
}
// Deletes a file on Dispose.
// (may be a struct?)
sealed class TemporaryFile : IDisposable
{
public TemporaryFile(string path);
public string Path { get; }
}
// Deletes a directory on Dispose.
// (may be a struct?)
sealed class TemporaryDirectory : IDisposable
{
public TemporaryDirectory(string path);
public string Path { get; }
} APIs for randomly naming: static class Directory
{
// Creates a uniquely named directory with access restricted to the current user.
public static string CreateTempDirectory();
}
static class File
{
// Creates a uniquely named file.
public static FileStream CreateTempFile(string directory, string extension = "tmp", FileAccess access = FileAccess.Write, FileShare share = FileShare.None, int bufferSize = 4096, FileOptions options = FileOptions.None);
} Example: using TemporaryDirectory tmpDir = new(Directory.CreateTempDirectory());
using FileStream file = File.CreateTempFile(tmpDir.Path); |
On windows for both UWP and Win32 apps distributed with MSIX packaging system it makes sense to use "%localappdata%/Packages/%PackageName%/TempState" as a temp folder location instead of global OS "Temp" folder heap. https://docs.microsoft.com/en-us/uwp/api/windows.storage.applicationdata.temporaryfolder?view=winrt-20348 It also does not requires any special permissions. |
it would be nice to have any chance of reviving this? the proposed API seems.... a bit extensive. can we maybe shoot for an easier target that could be introduced for net9? |
We need a more official, general purpose
TempFileCollection
that lives inSystem.IO
that allows you to:FileStream
instances (which is more dependable than taking creating your own from a string, and it is also encourages writing more secure code).We could extend
TempFileCollection
, but it is purpose built for CodeDom and isn't very discoverable. I'm not very keen on pushing that one forward.dotnet/corefx#41961, dotnet/corefx#22972, dotnet/corefx#24001 cover functionality requests that would be handled by this.
The text was updated successfully, but these errors were encountered: