如何在C#中删除包含只读文件的目录?
我需要删除包含只读文件的目录。 哪种方法更好:
使用
DirectoryInfo.Delete()
,或者,ManagementObject.InvokeMethod("删除")
?
使用 DirectoryInfo.Delete()
,我必须手动关闭每个文件的只读属性,但 ManagementObject.InvokeMethod("Delete")
似乎没有需要。 是否存在一种情况比另一种更可取的情况?
示例代码(test.txt 是只读的)。
第一种方式:
DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");
DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");
File.SetAttributes(@"C:\Users\David\Desktop\Test\test.txt", FileAttributes.Archive);
test.Delete(true);
第二种方式:
DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");
DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");
string folder = @"C:\Users\David\Desktop\Test";
string dirObject = "Win32_Directory.Name='" + folder + "'";
using (ManagementObject managementObject = new ManagementObject(dirObject))
{
managementObject.Get();
ManagementBaseObject outParams = managementObject.InvokeMethod("Delete", null,
null);
// ReturnValue should be 0, else failure
if (Convert.ToInt32(outParams.Properties["ReturnValue"].Value) != 0)
{
}
}
I need to delete a directory that contains read-only files. Which approach is better:
Using
DirectoryInfo.Delete()
, or,ManagementObject.InvokeMethod("Delete")
?
With DirectoryInfo.Delete()
, I have to manually turn off the read-only attribute for each file, but ManagementObject.InvokeMethod("Delete")
doesn't appear to need to. Is there any situation where one is more preferable to the other?
Sample code (test.txt is read only).
First way:
DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");
DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");
File.SetAttributes(@"C:\Users\David\Desktop\Test\test.txt", FileAttributes.Archive);
test.Delete(true);
Second way:
DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");
DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");
string folder = @"C:\Users\David\Desktop\Test";
string dirObject = "Win32_Directory.Name='" + folder + "'";
using (ManagementObject managementObject = new ManagementObject(dirObject))
{
managementObject.Get();
ManagementBaseObject outParams = managementObject.InvokeMethod("Delete", null,
null);
// ReturnValue should be 0, else failure
if (Convert.ToInt32(outParams.Properties["ReturnValue"].Value) != 0)
{
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
为了跟进 Vitaliy Ulantikov 的解决方案,我用重命名/移动文件夹方法对其进行了补充:
To follow up on Vitaliy Ulantikov's solution I have supplemented it with a rename/move folder method:
我针对 NET Framework 3.5 和 NET Framework 版本 4 及更高版本的解决方案:
用法:
My solution for NET framework 3.5 and for NET framework version 4 and higher:
Usage:
避免递归调用的最简单方法是在获取 FileSystemInfo 时使用 AllDirectories 选项,如下所示:
Simplest way of avoiding recursive calls is by utilising the
AllDirectories
option when gettingFileSystemInfo
s, like so:这是一个扩展方法,它递归地将
Attributes
设置为Normal
,然后删除项目:Here is an extension method which sets
Attributes
toNormal
recursively, then deletes the items:尝试这个,
Try this,
另一种方法不需要递归。
Another method without the need for recursion.
最好的解决方案是将所有文件标记为非只读,然后删除该目录。
请注意,~ 是一个按位逻辑运算符,它返回给定二进制值的补码。 我还没有测试过这个,但它应该有效。
谢谢!
The best solution is to mark all the files as non-read only, and then delete the directory.
Notice that ~ is a Bitwise logical operator which returns the complement of the given binary value. I haven't tested this, but it should work.
Thanks!
我想说你的第一种方法看起来更明确和可读。 第二种方法闻起来像反射,不是类型安全的,而且看起来很奇怪。
ManagementObject
可以代表多个事物,因此.InvokeMethod("Delete")
实际上删除一个目录并不明显。I would say that your first approach looks more explicit and readable. The second method smells like reflection, is not type safe and looks weird. The
ManagementObject
can represent multiple things, so it's not obvious that.InvokeMethod("Delete")
actually deletes a directory.从表面上看,使用 WMI 方法似乎比迭代整个文件系统更有效(例如假设目录有数十个或数千个文件)。 但我不知道WMI也不做迭代。 如果确实如此,那么更接近金属(再次假设)它应该会更有效。
为了优雅,我承认递归方法很酷。
性能测试应该回答效率问题。 如果包装在 DirectoryInfo 的扩展方法中,这两种方法都可以很优雅。
On the surface, using the WMI approach seems more efficient than iterating over the entire file system (assume for example the directory has 10's of thousands of files). But I do not know that WMI also doesn't do iterations. If it does, being closer to the metal (again, assumptions) it should be more efficient.
For elegance, I concede the recursive method is cool.
Performance testing should answer the efficiency question. And either can be elegant if wrapped in an extension method of DirectoryInfo.
这是另一种避免自身递归的解决方案。
这是通过在删除之前重置文件夹和文件的属性来实现的,因此您只需删除“DirectoryResetAttributes”方法的最后一行并单独使用删除即可。
与此相关的是,虽然这有效,但我在删除“太长”的路径时遇到了问题,最终使用了此处发布的 robocopy 解决方案: C# 删除具有长路径的文件夹
Here is another solution that avoids recursion on itself.
This works by resettings attributes on the folders and files before the delete, so you could just remove the last line for a 'DirectoryResetAttributes' method and use delete separately.
On a related note, while this worked, I then had issues with deleting paths that were 'too long' and ended up using a robocopy solution posted here: C# deleting a folder that has long paths