【问题标题】:What's the use of TempFileCollection.AddExtension if it doesn't return unique names?如果 TempFileCollection.AddExtension 不返回唯一名称,它有什么用?
【发布时间】:2015-10-30 09:02:50
【问题描述】:

出于调试目的,我需要创建三个临时 XML 文件。我正在使用 TempFileCollection,因为它符合要求,但显然 AddExtension 方法实际上并没有返回唯一的文件名。

根据to the MSDN

每个文件扩展名只能调用一次此方法,因为如果使用相同的扩展名调用它将返回相同的名称。

显然我只需要使用AddFile 方法添加我自己的文件。那这个方法有什么用呢?为了解决这个问题,我只是在使用

var filename = Guid.NewGuid().ToString + ".xml"
collection.AddFile(filename, false);

【问题讨论】:

  • 小心! Guid保证是唯一的。 (虽然不太可能不会)。
  • 确实如此,但是对于我在这个项目上进行的罕见的调试会话,安全性不是问题,无论如何文件都会在会话结束时被删除。

标签: c# .net file msdn


【解决方案1】:

根据 MSDN 中的 TempFileCollection 文档:

要为具有特定文件扩展名的临时文件生成唯一名称,请调用 AddExtension 并指定要生成的文件名的扩展名。 AddExtension 方法将返回一个字符串,该字符串由 TempDir 属性指定的目录中指定扩展名的文件名的完整路径组成。 AddExtension 方法只会返回一个唯一的文件名每个文件扩展名

TempFileCollection 位于 System.CodeDom.Compiler 命名空间中。如果您只想创建一些临时文件,请使用Path.GetTempFileName

Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
Console.WriteLine(Path.ChangeExtension(Path.GetTempFileName(), "xml"));
// You got three different files with .xml extension.

Path.GetTempFileName() 创建的文件不会被自动删除。要自动清理临时文件,请使用 System.IO.FileOptions.DeleteOnClose。请参阅Windows temporary files behaviour - are they deleted by the system? 的类似问题。一段示例代码是这样的

var path = Path.GetTempFileName();
Console.WriteLine(path);
using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4000, 
    FileOptions.DeleteOnClose))
{
    fs.WriteByte(65);
}

我知道包含其他不相关的参数是愚蠢的,但这就是这个 API 的设计方式。您可以将fs 包裹在其他steam 中或传递给XDocument/XElement.Save()

var e = new XElement("Node");
e.Save(fs);

【讨论】:

  • 我使用 TempFileCollection 对象只是因为它可以满足我的需要:使用完临时文件后会自动清理它们。别人已经处理过的事情为什么要重写?我的问题是专门询问这种方法的实用性。该方法的签名(输入扩展名,是否保留文件,并取回文件名)似乎暗示它每次都会为您生成一个新文件。事实证明,它只会创建一个唯一的文件并继续返回。对我来说没有任何意义。
  • @MrDoom,如果您希望它们被自动删除,请使用System.IO.FileOptions.DeleteOnClose。在stackoverflow.com/questions/324045/… 上查看更多信息。
【解决方案2】:

TempFileCollection 并不是为您创建临时的fileNames,它只会保存临时文件,并会根据 Delete() 中的请求或在处理集合时删除它们。见 a.o.属性 KeepFiles。

要生成唯一的文件名,请使用 System.IO.Path.GetTempFileName 和 System.IO.Path.changeExtension

【讨论】:

  • 但它显然会,因为第一次调用 AddExtension 返回一个唯一命名的文件。但是,第二次调用仅返回相同的文件。我知道我需要自己执行外部步骤,但是此时 AddExtension 的目的是什么?某种形式的池化?
【解决方案3】:

TempFileCollection 位于 System.CodeDom.Compiler 命名空间中。这意味着编译器可以使用它。

基于此,我可以查看TempFileCollection 的两个不同用例:

  • 创建一组不相关的临时文件,并确保在之后清理它们。
  • 创建一组具有不同扩展名的相关文件,并确保之后清理它们。

对于第二项(相关文件),只需查看binobj 文件夹即可。您可能有多个文件对应于同一个文件。例如:

  • Program.exe
  • Program.exe.config
  • Program.pdb

因此,我将为与Program 相关的所有文件创建一个TempFileCollection。然后,我可以调用AddExtension 来获取.exe 文件的临时文件。我不需要将该路径存储在变量中 - 我只需再次调用 AddExtension 即可获得相同的路径。

TL;DR:

  • AddFile 用于第一个用例(不相关的临时文件)
  • AddExtension 用于第二个用例(相关的临时文件,都具有唯一的扩展名)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2013-02-27
    相关资源
    最近更新 更多