14

我需要在我的 Windows Forms .NET 3.5 应用程序中处理一些临时文件。这些文件是在一个外部应用程序中打开的,当然它可以运行比我自己的程序更长的时间。

是否有任何最佳实践来确保随时清理这些临时文件,以避免用户的硬盘充满不再需要的“垃圾”文件?或者甚至 Windows 会自动处理这个问题吗?

一个很好的例子是任何邮件客户端:当您在任何应用程序中打开一个附件时,它通常被写入一个打开的临时文件。有没有办法弄清楚这些文件如何管理清理?

使用 Google 向我展示了许多清理和调整工具来手动清理临时目录,但我不想强迫用户这样做。:-)

4

8 回答 8

28

在 .NET 中,您可以使用TempFileCollection该类来管理一组要由您的应用程序清理的临时文件(请注意,它相当隐藏在 CodeDom 命名空间中)。显然,您不能删除任何不属于您自己的文件,因为这些文件可能仍被另一个应用程序打开(删除它们可能会导致严重问题)。

于 2009-03-18T17:41:02.510 回答
7

清理临时文件的责任应该在创建它们的应用程序上。这很容易。我使用一个看起来像这样的类:

public class TempFile : IDisposable
{
    public TempFile()
    { this.path = System.IO.Path.GetTempFileName(); }

    public void Dispose()
    { File.Delete(path); }

    private string path;
    public string Path { get { return path; } }
}

如果您需要清理另一个应用程序的临时文件,它需要一些与您的通信的方法。至少它应该能够提供信号量。然而,这样做的复杂性大于让原始应用程序处理自己的文件的复杂性。

于 2009-03-18T19:01:46.247 回答
5

如果您尝试确定性地清除临时文件类型文件夹的内容,则可能会删除其他进程正在使用的文件。Windows 操作系统提供了一些工具,允许用户在卷的可用磁盘空间达到某个阈值时删除这些文件。

现在,如果您可以确定在使用特定临时文件后将不再需要它,那么删除该特定文件没有任何不利之处。

于 2009-03-18T17:40:21.327 回答
2

我们有一个类似的文件生命周期问题——(winforms)应用程序可以从中央存储库中获取一个文档供用户查看,但用户应该能够关闭我们的应用程序而不影响他们正在查看的文件。出于安全考虑,需要清理文档文件,以免它们放置太久。

我们使用的解决方案是在用户的隔离存储区域中创建一个具有日期派生名称的文件夹,并将其用作今天的缓存。在应用程序关闭和启动时,我们检查以前过时的缓存文件夹并删除它们(和内容)。

于 2009-05-21T11:04:56.273 回答
1

我相信当用户注销时它们会被删除。

回到人们每天关闭电脑的时代,这可能是一个完美的解决方案。

现在,人们可能会在几个月内不注销,因此依赖它可能不是一个好主意。

此外,如果他们在不关闭机器的情况下关闭机器,那么文件也不会被删除。

您可以使用文件系统监视器来监视您编写的文件,并等待一段时间不活动(10 分钟、1 小时、1 天或其他任何时间),然后删除该文件。

但这并不适用于所有事情。一些程序可能有一个文件“打开”,但可能没有锁定底层文件。如果发生这种情况,那么您将无法知道何时可以安全地删除该文件。

但是,我认为您可能会忽略这个问题。无论如何,大多数人可能都有多余的硬盘空间,所以他们可能不太可能遇到它。如果他们这样做了,我认为 Windows 会弹出一个磁盘空间不足的对话框,让他们可以选择清除临时目录,这将解决问题。

更新:

我认为 Windows Update 大约会每月重新启动一次用户的计算机,因此在发生这种情况时应该清除临时文件。

不能保证不会有问题,但在实践中我认为应该很少见。

更新 2:

在评论的提示下,我去实际测试了这个,看起来 Windows 在用户注销时不会删除临时文件。但是,我仍然说,在 OP 的情况下,这不是一个真正的问题。当它出现问题时(因为磁盘空间不足),Windows 会提示用户删除临时文件。

于 2009-03-18T17:47:32.323 回答
1

在 ASP.NET 中使用临时文件时,请使用 PAGE_DISPOSED 事件删除您在页面中创建的任何临时文件。否则,您最终可能会与直到 DISPOSED 才放手的组件发生争用。

于 2009-08-06T19:20:55.597 回答
1

我使用这个解决方案(非常可靠):

using System.IO;
using System.Reflection;

namespace Konard.Helpers
{
    public static partial class TemporaryFiles
    {
        private const string UserFilesListFilenamePrefix = ".used-temporary-files.txt";
        static private readonly object UsedFilesListLock = new object();

        private static string GetUsedFilesListFilename()
        {
            return Assembly.GetEntryAssembly().Location + UserFilesListFilenamePrefix;
        }

        private static void AddToUsedFilesList(string filename)
        {
            lock (UsedFilesListLock)
            {
                using (var writer = File.AppendText(GetUsedFilesListFilename()))
                    writer.WriteLine(filename);
            }
        }

        public static string UseNew()
        {
            var filename = Path.GetTempFileName();
            AddToUsedFilesList(filename);
            return filename;
        }

        public static void DeleteAllPreviouslyUsed()
        {
            lock (UsedFilesListLock)
            {
                var usedFilesListFilename = GetUsedFilesListFilename();

                if (!File.Exists(usedFilesListFilename))
                    return;

                using (var listFile = File.Open(usedFilesListFilename, FileMode.Open))
                {
                    using (var reader = new StreamReader(listFile))
                    {
                        string tempFileToDelete;
                        while ((tempFileToDelete = reader.ReadLine()) != null)
                        {
                            if (File.Exists(tempFileToDelete))
                                File.Delete(tempFileToDelete);
                        }
                    }
                }

                // Clean up
                using (File.Open(usedFilesListFilename, FileMode.Truncate)) { }
            }
        }
    }
}

每次您需要临时文件使用时:

var tempFile = TemporaryFiles.UseNew();

确保在应用程序关闭或崩溃后删除所有临时文件

TemporaryFiles.DeleteAllPreviouslyUsed();

在应用程序开始时。

于 2014-11-19T14:03:46.207 回答
0
  • 您可以创建一个临时文件,在其中您可以继续写入过程中创建的文件名,在处理结束时您可以(前提 - 实现 IDisposable 并)在操作完成后在 Disponse 方法中删除。

  • 另一种方法是编写独立的进程,每个间隔执行清理。

  • 在文件末尾附加日期,并在具有该日期的那一天结束时删除,进程将在末尾生成带有新日期的新文件。

  • divo tempfilecollection 类给出的一个很好的建议。

希望能帮助到你。

于 2009-08-06T19:28:26.050 回答