代码之家  ›  专栏  ›  技术社区  ›  Nifle Hassan Syed

如何在c#中自动删除临时文件?

  •  50
  • Nifle Hassan Syed  · 技术社区  · 16 年前

    现在,我保留了一个临时文件列表,并使用Application.ApplicationExit上触发的EventHandler删除它们。

    有更好的办法吗?

    9 回复  |  直到 4 年前
        1
  •  81
  •   Marc Gravell    16 年前

    如果进程过早终止,则无法保证任何结果,但是,我使用“ using “这么做。。

    using System;
    using System.IO;
    sealed class TempFile : IDisposable
    {
        string path;
        public TempFile() : this(System.IO.Path.GetTempFileName()) { }
    
        public TempFile(string path)
        {
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            this.path = path;
        }
        public string Path
        {
            get
            {
                if (path == null) throw new ObjectDisposedException(GetType().Name);
                return path;
            }
        }
        ~TempFile() { Dispose(false); }
        public void Dispose() { Dispose(true); }
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                GC.SuppressFinalize(this);                
            }
            if (path != null)
            {
                try { File.Delete(path); }
                catch { } // best effort
                path = null;
            }
        }
    }
    static class Program
    {
        static void Main()
        {
            string path;
            using (var tmp = new TempFile())
            {
                path = tmp.Path;
                Console.WriteLine(File.Exists(path));
            }
            Console.WriteLine(File.Exists(path));
        }
    }
    

    TempFile 被处置或垃圾回收时,文件将被删除(如果可能)。很明显,您可以根据自己的喜好,或者在某个地方的集合中使用它。

        2
  •  69
  •   piedar    8 年前

    考虑使用Fielopys.DeleTeOnCuffel旗:

    using (FileStream fs = new FileStream(Path.GetTempFileName(),
           FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None,
           4096, FileOptions.RandomAccess | FileOptions.DeleteOnClose))
    {
        // temp file exists
    }
    
    // temp file is gone
    
        3
  •  20
  •   David Grant    16 年前

    你可以 P/Invoke CreateFile FILE_FLAG_DELETE_ON_CLOSE 旗帜这会告诉Windows在关闭所有句柄后删除该文件。另见: Win32 CreateFile docs .

        4
  •  7
  •   Community basarat    7 年前

    TempFileCollection 类,因为它是内置的,在旧版本的.NET中可用,并实现 IDisposable 接口,因此如果与 "using"

    下面是一个从嵌入式资源(通过项目属性页->资源选项卡添加)中提取文本的示例,如下所述: How to embed a text file in a .NET assembly? "EmbeddedResource" 在嵌入文件的属性设置中)。

        // Extracts the contents of the embedded file, writes them to a temp file, executes it, and cleans up automatically on exit.
        private void ExtractAndRunMyScript()
        {
            string vbsFilePath;
    
            // By default, TempFileCollection cleans up after itself.
            using (var tempFiles = new System.CodeDom.Compiler.TempFileCollection())
            {
                vbsFilePath= tempFiles.AddExtension("vbs");
    
                // Using IntelliSense will display the name, but it's the file name
                // minus its extension.
                System.IO.File.WriteAllText(vbsFilePath, global::Instrumentation.Properties.Resources.MyEmbeddedFileNameWithoutExtension);
    
                RunMyScript(vbsFilePath);
            }
    
            System.Diagnostics.Debug.Assert(!File.Exists(vbsFilePath), @"Temp file """ + vbsFilePath+ @""" has not been deleted.");
        }
    
        5
  •  5
  •   Konard    10 年前

    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();
    

    在应用程序开始时。

        6
  •  3
  •   Pang firemonkey    4 年前

    很高兴看到您想负起责任,但是如果文件不是很大(>50MB),您将与所有人(包括MS)一样,将它们保留在临时目录中。磁盘空间丰富。

    csl posted ,GetTempPath是一条路要走。空间不足的用户将能够运行磁盘清理,您的文件(以及其他人的)将被清理。

        7
  •  3
  •   Pang firemonkey    4 年前

    我不是一个主要的C程序员,但是在C++中我会使用 RAII hints on using RAII-like behaviour in C# 在线,但大多数似乎使用的终结器是不确定的。

    我认为有一些Windows SDK函数可以创建临时文件,但不知道它们是否会在程序终止时自动删除。有一个 GetTempPath

    附言 C# destructor documentation 说你可以而且应该在那里发布资源,我觉得有点奇怪。如果是这样的话,您可以简单地删除析构函数中的临时文件,但这可能不是完全确定的。

        8
  •  0
  •   Austin Salonen gmlacrosse    16 年前

    您可以在启动时启动一个线程,该线程将删除那些“不应该”从崩溃中恢复的文件。

        9
  •  -2
  •   Zach    9 年前

    如果要构建Windows窗体应用程序,可以使用以下代码:

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            File.Delete("temp.data");
        }