打开只读文件

64

目前,这是我打开文件并读取它的方法:

 using (TextReader reader = new StreamReader(Path.Combine(client._WorkLogFileLoc, "dump.txt")))
{
    //do stuff
}

我如何以只读模式打开文件,这样如果另一个进程同时打开了该文件,我的程序仍然可以读取它。


你想以读取模式打开流吗?还是想设置文件属性为只读? - The Scrum Meister
请注意,如果另一个进程已经打开了文件,则该进程仍然必须启用读取共享才能让您读取它。如果其他进程以拒绝共享的方式打开文件,则即使只以只读方式打开文件也将被阻止。有关更多信息,请参见FileShare枚举(或Win32等效项)。 - itowlson
4个回答

150

典型问题是另一个进程正在写入该文件。所有标准的File方法和StreamReader构造函数都使用FileShare.Read打开文件。这不能工作,它拒绝了写共享。你不能拒绝写,其他进程已经获取了写访问权限。因此,你将被拒绝访问。

你必须像这样使用FileShare.ReadWrite:

var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
using (var sr = new StreamReader(fs))
{
    // etc...
}

请注意,您仍将面临一个棘手的问题,即您正在读取一个未完成的文件。另一个进程在随机时间点刷新数据到文件中,您可能只读取了一半的文本行。结果可能因人而异。


谢谢。看起来这就是我在寻找的东西。由于我的程序处理文件读取的方式,读取半写文件对我来说不是问题。 - Ayush
太感谢了!正如你所说,所有其他函数都是使用FileShare.Read打开的。我已经尝试了很长时间,使用不同变体的streanreader函数来解决问题...! - Milind Thakkar
完美地工作了。正是我所需要的。谢谢! - Bruce Thompson

15

如果你想以只读模式打开文件,请尝试以下方法:

using (TextReader reader 
   = new StreamReader(File.OpenRead(Path.Combine(client._WorkLogFileLoc, "dump.txt")))) 
{     
         //do stuff 
} 

注意调用File.OpenRead()方法。


太遗憾了,你比我快了几秒。;p 给你加一分。 - Brad Christie

4
您可以通过调用File.SetAttributes来设置文件属性。
string path = Path.Combine(client._WorkLogFileLoc, "dump.txt");
FileAttributes curAttributes = File.GetAttributes(path);
File.SetAttributes(path, curAttributes | FileAttributes.ReadOnly);

我只是想知道:在一个进程/线程中设置文件属性,是否会影响正在访问该文件以进行写访问的其他进程/线程? - Fredrick Gauss

-1

根据https://learn.microsoft.com/en-us/dotnet/api/system.io.file.openread?redirectedfrom=MSDN&view=netcore-3.1#System_IO_File_OpenRead_System_String_,File.OpenRead允许读取共享访问而不是读/写。这可以防止“其他进程”能够关闭/重新打开/写入更多数据,正如xbonez想要允许的那样。hans-passant解决了所请求的问题。

根据引用的文档:此方法等效于使用FileMode值为Open、FileAccess值为Read和FileShare值为Read的FileStream(String, FileMode, FileAccess, FileShare)构造函数重载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接