为什么不能重命名在流中打开的文件?

时间:2013-02-08 15:43:08

标签: c# .net

使用以下代码,我读取一个文件并保持流打开。

    static void Main(string[] args)
    {
        FileStream fileStream = new FileStream(@"C:\temp\test1.txt", FileMode.Open);
        Console.ReadLine();
    }

如果我现在尝试重命名此文件,则会显示“正在使用的文件”消息。 file in use

看起来文件的重命名应该是可行的(在操作系统级别上),即使它正在使用中:Why does rename a loaded .net assembly work?

为什么文件在通过.net?

加载到流中时无法重命名

2 个答案:

答案 0 :(得分:2)

关于程序集,.NET应该使用FileShare.ReadWrite之类的东西打开程序集,这样即使它被加载到域中,任何其他进程也可以写入或重命名整个文件。

AFAIK,.NET没有托管FileShare枚举值来允许或禁止重命名文件共享(类似FileShare.Rename),但Win32应该有汇编加载会创建文件带有FileShare.ReadWrite | FileShare.RenameFileShare.Delete等掩码的流包括重命名,但也删除整个文件......)。

为了证明这一点,我尝试了以下代码:

    FileStream a = File.Open(@"C:\blah.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    a.Dispose();

虽然文件流已经打开,直到它被丢弃,但我无法删除整个文件,但我可以重命名它。

请注意,程序集在需要时会加载到AppDomain中,这意味着您可以编写,删除或重命名程序集,因为它尚未加载。

尝试删除已加载到AppDomain的程序集:你不能(我刚刚尝试过,测试代码在控制台应用程序中运行,我无法在运行时删除可执行文件) )。现在尝试重命名它:它有效。

摘要

关于如何打开文件以及在打开文件流时使用了哪种文件掩码配置:这就是为什么您的文件无法重命名但您可以重命名已加载的程序集的全部内容

修改您的代码,就像下一个代码一样,您将能够重命名整个文件(甚至删除它!):

    FileStream fileStream = File.Open(@"C:\temp\test1.txt", FileMode.Open, FileShare.ReadWrite | FileShare.Delete);
    Console.ReadLine();

答案 1 :(得分:1)

创建FileStream时,不要将其数据加载到内存中。 当你在寻找流时,仍然会从磁盘中读取文件内容 - 当你需要阅读大文件时,这是一件好事。

如果您只想将整个内容加载到内存中,则可以使用File.ReadAllBytes。 您可以在此处详细了解:http://msdn.microsoft.com/en-us/library/system.io.file.readallbytes.aspx

注意:如果要使用流而不是字节数组,可以使用MemoryStream并将读取文件内容传递给它。