c# - FileOptions.DeleteOnClose Windows 是特定的吗?
问题描述
我正在尝试使用 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
}
上面的代码片段来自第 261-269 行,src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs
也是实现的一部分FileStream.Dispose
。
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 的系统上不会被删除。
推荐阅读
- python - 使用 python/pynco 初始化 Nco 对象时出现 TypeError
- tomcat - 页面太大时Tomcat无法转发错误代码500
- android - 在 Cordova 中检测 Android 上的显示切口 // Ionic
- powershell - 如何从 powershell 脚本中向 TFS vNext 报告构建进度?
- scheme - 计划中的 DFA(家庭作业)
- python - 在熊猫数据框上应用 groupby 两次
- python - 使用换行符将 StringIO 对象写入 csv 文件
- javascript - 检索画布上元素的 ID
- string - 如何在 GO 中操作字符串以反转它们?
- java - 我收到设置跨度错误设置跨度在 0 之前开始