2012-11-01 34 views
2

问题我有以下代码读取文件与StreamReader的,ThreadSafety和读取模式

StreamReader str = new StreamReader(File.Open(fileName, FileMode.Open, FileAccess.Read)); 
string fichier = str.ReadToEnd(); 
str.Close(); 

这是一个asp.net web服务的一部分,并在生产中一直在努力罚款的一年了。现在随着服务器负载的增加,客户已经开始变得“​​文件已被使用”错误。该文件正在从该代码读取,并且从不写入应用程序。

我清楚地看到的一个问题是我们没有缓存文件的内容以供将来使用。我们会这样做。但我需要明白为什么以及如何解决这个问题。

是否因为多个线程试图读取文件?我读到StreamReader不是线程安全的,但为什么当我在Read模式下打开文件时它会成为问题?

回答

3

您需要打开允许读访问的文件。使用File.Open这个超载来指定文件共享模式。您可以使用FileShare.Read来允许读取此文件。

Anothr可能的解决方案是将该文件一次加载到内存中的类的静态构造函数中,然后将内容存储在静态只读变量中。由于静态构造函数保证只运行一次并且是线程安全的,因此您无需执行任何特殊的操作就可以使其工作。

如果您永远不会更改内存中的内容,您访问数据时甚至不需要锁定。如果您更改了内容,则需要先在每次要更改时都克隆这些数据,但是再次,由于实际原始数据不会更改,因此不需要锁定克隆操作。

例如:

public static class FileData 
{ 
    private static readonly string s_sFileData; 

    static FileData() 
    { 
     s_sFileData = ...; // read file data here using your code 
    } 

    public static string Contents 
    { 
     get 
     { 
      return (string.Copy (s_sFileData)); 
     } 
    } 
} 

此封装你的数据,让您只读访问。

如果您的代码可能会修改文件内容,您只需要String.Copy() - 这只是一种强制创建新字符串实例以保护原始字符串的预防措施。由于string是不可变的,所以只有当你的代码使用字符串指针时才需要 - 我只添加了这一点,因为我刚刚在我自己的代码中遇到了类似变量的问题,上个星期我使用指向缓存数据的指针。 :)

1

FileMode只是控制你可以做什么(读/写)。

共享访问的文件,在操作系统级别的处理,您可以要求行为与文件共享(第三个参数),见doc