我正在尝试使用 FileStream 和 FileOptions.DeleteOnClose 创建一个临时文件。当流被关闭时,我看到了预期的行为,但是如果抛出异常,则文件不会被删除。我无法使用 using
,因为流的关闭由 FileStreamResult 处理。我知道在 Windows 上它由 winapi 标志 FILE_FLAG_DELETE_ON_CLOSE 处理,但我不知道这是否/如何适用于 .NET Core 应用程序上的其他平台。
我已经尝试围绕此包装一个 try-catch 以在错误情况下手动处理流,这确实有效但应该是不必要的,因为一旦释放所有句柄,文件就会被删除。
const FileOptions fileOptions =
FileOptions.Asynchronous |
FileOptions.DeleteOnClose |
FileOptions.Encrypted |
FileOptions.SequentialScan;
var fileStream = new FileStream(
Path.GetRandomFileName(),
FileMode.Create,
FileAccess.ReadWrite,
FileShare.None,
4096,
fileOptions);
如果 FileOptions.DeleteOnClose 是跨平台的,我希望在释放所有句柄时删除文件,但文件仍然存在。
最佳答案
阅读src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs
的源代码,似乎FileOptions.DeleteOnClose
是在处置时在 *nix 平台上受到尊重和模仿:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ...
// If DeleteOnClose was requested when constructed, delete the file now.
// (Unix doesn't directly support DeleteOnClose, so we mimic it here.)
if (_path != null && (_options & FileOptions.DeleteOnClose) != 0)
{
// Since we still have the file open, this will end up deleting
// it (assuming we're the only link to it) once it's closed, but the
// name will be removed immediately.
Interop.Sys.Unlink(_path); // ignore errors; it's valid that the path may no longer exist
}
以上片段来自lines 261-269 of src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs
和 FileStream.Dispose
的一部分实现。
我创建了一个 Gist with the following test code :
using System.IO;
var fileName = Path.GetRandomFileName();
Console.WriteLine($"File name: {fileName}");
Console.WriteLine($"Exists? {File.Exists(fileName)}");
using (var fs = File.Create(fileName, 4096, FileOptions.DeleteOnClose))
Console.WriteLine($"Exists? {File.Exists(fileName)}");
Console.WriteLine($"Exists? {File.Exists(fileName)}");
然后使用 Docker 在 Linux 上使用 .NET Core SDK 3.1 进行测试,如下所示:
> docker run --rm -it mcr.microsoft.com/dotnet/core/sdk:3.1
> root@86a890d817b7:/# dotnet tool install dotnet-script --version 0.53.0 --tool-path /usr/bin
You can invoke the tool using the following command: dotnet-script
Tool 'dotnet-script' (version '0.53.0') was successfully installed.
> root@86a890d817b7:/# dotnet script https://gist.github.com/atifaziz/2a0291a076c77e197d849eab7c049b1b/raw/9b5a08c0ffd45e09eac19325445b9fbdf799e10c/test.csx
File name: hrylnqis.nxv
Exists? False
Exists? True
Exists? False
输出似乎证实了 FileOptions.DeleteOnClose
正在按预期工作,因此,不,根据您的问题,它不是特定于 Windows 的。
不过请记住,由于 DeleteOnClose
是为 Unix(的某些定义)模拟的,因此它没有像在 Windows 上那样的强大保证。例如,如果进程崩溃或通过 Environment.Exit
残酷退出那么该文件将在 Windows 上被删除,但在基于 Unix 的系统上不会被删除。
关于c# - FileOptions.DeleteOnClose Windows 是特定的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57176254/