简体   繁体   English

打开文件没有(真的)锁定它?

[英]Open file without (really) locking it?

Is it possible to open a file in a way that allows subsequent deletion/renaming of its parent folder? 是否可以以允许后续删除/重命名其父文件夹的方式打开文件?

I know you can do this: 我知道你可以这样做:

File.Open("foo.bar", FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)

Which will allow for the file to be deleted when the file handle is closed. 这将允许在关闭文件句柄时删除文件。 However, if it does not allow the parent folder to be deleted without error. 但是,如果它不允许删除父文件夹而没有错误。

I couldn't find anything in the framework. 我在框架中找不到任何东西。 Have I overlooked something, or is there a native API I can interop to. 我是否忽略了某些东西,或者是否存在我可以互操作的原生API。

Note: I don't care if I get an exception when using the stream of the deleted file. 注意:在使用已删除文件的流时,我不在乎是否出现异常。 In fact that would be ideal. 事实上,这将是理想的。

UPDATE: 更新:

So the most promising idea was the Hardlink , however I just can't make it work. 所以最有希望的想法是Hardlink ,但是我无法让它发挥作用。 I still end up with Access Denied when i try to delete the parent directory. 当我尝试删除父目录时,我仍然最终拒绝访问。 Here is my code: 这是我的代码:

class Program
{
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);

    static void Main(string[] args)
    {
        string hardLinkPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        string realPath = @"C:\foo\bar.txt";
        if (CreateHardLink(hardLinkPath, realPath, IntPtr.Zero))
        {
            using (FileStream stream = File.Open(hardLinkPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
            {
                Console.Write("File locked");
                Console.ReadLine();
            }

            File.Delete(hardLinkPath);
        }
        else
            Console.WriteLine("LastError:{0}", Marshal.GetLastWin32Error());
    }
}

如果您正在使用NTFS,您可以在临时位置创建另一个文件的硬链接,您将避免文件复制开销,并且第一个链接仍然可以删除(文件本身或包含目录)而不会影响第二。

The best solution I can come up with, is to copy the file to a temporary scratch location. 我能想到的最好的解决方案是将文件复制到临时的临时位置。 Then, open the temp file, and delete it when I'm finished. 然后,打开临时文件,并在完成后删除它。

FileOpen uses CreateFile in Kernel32.dll. FileOpen在Kernel32.dll中使用CreateFile I'm not sure you'll be able to achieve anything more than the .NET framework provides you with, as all the options are already there, unless you perform it as a transaction . 我不确定你能否实现除.NET框架之外的任何东西,因为所有选项都已存在,除非你将它作为一个事务执行。

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

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