Tim*_*meh 5 c# cross-platform file .net-core
我正在尝试使用 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);
Run Code Online (Sandbox Code Playgroud)
如果 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
}
Run Code Online (Sandbox Code Playgroud)
上面的代码片段来自实现的第 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)}");
Run Code Online (Sandbox Code Playgroud)
然后使用 Docker 在带有 .NET Core SDK 3.1 的 Linux 上进行测试,如下所示:
> 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
Run Code Online (Sandbox Code Playgroud)
输出似乎确认FileOptions.DeleteOnClose正在按预期工作,所以,不,根据您的问题,它不是特定于 Windows 的。
但请记住,由于DeleteOnClose是针对 Unix(的某些定义)进行模拟,因此它没有与 Windows 上相同的强有力的保证。例如,如果进程崩溃或粗暴退出,Environment.Exit那么该文件将在 Windows 上被删除,但在基于 Unix 的系统上不会被删除。
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |