我想在独占模式下打开一个文件进行读取,如果某个进程/线程已经打开了该文件,我想收到一个异常。我尝试了下面的代码,但没有工作,即使我打开了foo.txt,我仍然可以访问Console.WriteLine语句。有什么想法吗?
static void Main(string[] args)
{
using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
FileAccess.Read, FileShare.None))
{
Console.WriteLine ("I am here");
}
return;
}
答案 0 :(得分:19)
你在做什么是正确的。可能你只是错误地测试它。您应该使用在文件打开时锁定文件的程序打开它。记事本不会这样做。您可以运行两次应用程序以查看:
static void Main(string[] args)
{
// Make sure test.txt exists before running. Run this app twice to see.
File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None);
Console.ReadKey();
}
答案 1 :(得分:3)
你所做的是正确的。
如果您需要已经打开的所有文件,那么有一种方法可以通过NtQuerySystemInformation看到
您可以从http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx
获得想法获取目录中打开的所有文件..无论是否打开,都可以扩展为单个文件...
答案 2 :(得分:3)
通过编写一个打开文件的简单控制台模式程序来测试它,然后等待:
static void Main(string args[])
{
using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
Console.Write("File is open. Press Enter when done.");
Console.ReadLine();
}
}
从命令行(或Visual Studio的另一个实例)运行该程序,然后运行您的程序。这样,您可以使用FileMode和FileShare的不同值来确保您的程序在所有情况下都能正确响应。
而且,不,您不必检查文件是否先打开。如果文件已经打开,您的代码应该抛出异常。所以你要做的就是处理这个异常。
答案 3 :(得分:2)
我建议使用FileAccess.ReadWrite
成员,因为某些文件可能已经打开但允许您Read
访问该文件。但是,我猜想在非特殊情况下,所有为Read/Write
访问权限打开的文件都不允许您的代码Write
到该文件。
当然(正如Mehrdad已经解释的那样),如果您使用记事本之类的编辑器将文件作为测试打开,您将无法限制访问,因为记事本根本不会锁定文件。
答案 4 :(得分:2)
FileShare.None仅在其他进程也打开文件而不允许为读取共享时才有效。
Notepad和Visual Studio等程序不会锁定文本文件。