简体   繁体   English

当文件被其他进程删除时,文件流会发生什么?

[英]What happens to a filestream when the file is deleted by a different process?

In C#, I open a file with FileShare.Delete. 在C#中,我用FileShare.Delete打开一个文件。 This allows me to open the file without restricting other processes from deleting it. 这允许我打开文件而不限制其他进程删除它。 For example: 例如:

using (FileStream fs = new FileStream(@"C:\temp\1.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
{
    int len = (int)fs.Length;
    byte[] array = new byte[len];
    int bytesRead = fs.Read(array, 0, len);
}

My questions are: 我的问题是:

  1. What happens if the file is deleted by a different process after we created the stream, but before we read it? 如果在我们创建流之后,但在我们阅读之前,文件被其他进程删除会发生什么? Does the operating system keep a copy of the file until the stream\\handle is closed? 在流\\句柄关闭之前,操作系统是否保留文件的副本?
  2. Can I rely on reading the deleted file without getting any errors, or the wrong content? 我可以依赖于读取已删除的文件而不会收到任何错误或错误的内容吗?

The file is marked for deletion, but is not actually deleted until the last open handle to it is closed, as described in the documentation for DeleteFile . 该文件被标记为删除,但在关闭它的最后一个打开句柄之前, 实际上并未删除该文件,如DeleteFile文档中所述。

Note that you cannot open a new handle to a file that is marked for deletion, but the file will still appear in directory listings and cannot be replaced by a file of the same name until it has actually been deleted. 请注意,您无法打开标记为删除的文件的新句柄,但该文件仍将显示在目录列表中,并且在实际删除之前不能替换为同名文件。 This is unlike Unix systems in which the file disappears from the directory (is "unlinked") immediately. 这与Unix系统不同,在Unix系统中文件立即从目录中消失(“未链接”)。 As Ben suggests in the comments, you can work around this by renaming and/or moving the file before deleting it. 正如Ben在评论中建议的那样,您可以通过在删除文件之前重命名和/或移动文件来解决此问题。

Also, as MoonRabbit pointed out, you can "delete" an open file using Explorer, but that is because that only moves the file to the recycle bin. 此外,正如MoonRabbit指出的那样,您可以使用资源管理器“删除”一个打开的文件,但这是因为它只会将文件移动到回收站。 The Shift+Delete option to delete a file immediately won't work. 用于立即删除文件的Shift + Delete选项将不起作用。

Yes another process can delete the file but you will not get any exception as the pointer to the file on the disk was created so your process will continue reading, but when you retry to open the stream you will get an exception as the entry in the file system does not exist 是的另一个进程可以删除该文件,但您不会得到任何异常,因为创建了磁盘上文件的指针,因此您的进程将继续读取,但是当您重试打开流时,您将获得一个异常作为文件系统不存在

here a full example to reproduce your case 这里有一个重现你的案例的完整例子

try to execute this and go to explorer and delete your file 尝试执行此操作并转到资源管理器并删除您的文件

 class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10000; i++)
            {
                File.AppendAllText(@"c:\temp\1.txt", Guid.NewGuid().ToString());  
            }
            //read the file 
            using (FileStream fs = new FileStream(@"C:\temp\1.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
            {
                while (fs.CanRead)
                {
                    //here I read a chunk of 1000 bytes to let stream open 
                    int len = 1000;
                    Thread.Sleep(1000);
                    byte[] array = new byte[len];
                    int bytesRead = fs.Read(array, 0, len);
                }
            }

        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM