在C#中读取锁定文件的侵入性最小的方法是什么(可能是在不安全模式下)?

时间:2010-08-24 20:14:35

标签: c# file locking

我需要读取可能被锁定的Windows文件,但我不想创建任何类型的锁,以防止其他进程写入该文件。

此外,即使文件被锁定以供独家使用,我也希望看到里面的内容。

虽然这不是我的确切用例,但请考虑如何在使用和装载时读取SQL / Exchange日志或数据库文件。我不想导致腐败,但我仍然希望看到文件的内部并阅读它。

3 个答案:

答案 0 :(得分:47)

您可以在不复制文件的情况下执行此操作,请参阅this文章:

诀窍是使用FileShare.ReadWrite(来自文章):

private void LoadFile()
{
    try
    {
        using(FileStream fileStream = new FileStream(
            "logs/myapp.log",
            FileMode.Open,
            FileAccess.Read,
            FileShare.ReadWrite))
        {
            using(StreamReader streamReader = new StreamReader(fileStream))
            {
                this.textBoxLogs.Text = streamReader.ReadToEnd();
            }
        }
    }
    catch(Exception ex)
    {
        MessageBox.Show("Error loading log file: " + ex.Message);
    }
} 

答案 1 :(得分:15)

接受的答案不正确。如果文件确实被锁定,则不能只更改文件共享。如果已使用此文件共享选项设置了锁,但这并不意味着它就是这种情况。实际上,您可以通过在没有FileShare.ReadWrite的情况下打开文件来轻松地测试@CaffGeek解决方案,而不是尝试使用此标志将其打开到ReadWrite。你会得到另一个进程正在使用该文件。

代码:

        string content;
        var filePath = "e:\\test.txt";

        //Lock Exclusively the file
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);

        //CaffGeek solution
        using (FileStream fileStream = new FileStream(
        filePath,
        FileMode.Open,
        FileAccess.Read,
        FileShare.ReadWrite))
        {
            using (StreamReader streamReader = new StreamReader(fileStream))
            {
                content = streamReader.ReadToEnd();
            }
        }

如你所见,它崩溃了。此结果与File.Open等任何FileStream方法相同。它会在开放阶段崩溃你为FileShare提供的任何内容。

        //OPEN FOR WRITE with exclusive
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);


        //OPEN FOR READ with file share that allow read and write
        var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash

复制文件也不是一种选择。您可以通过独占打开文件来尝试自己,并尝试在Windows资源管理器上或通过代码复制文件:

        var filePath = "e:\\test.txt";
        var filePathCopy = "e:\\test.txt.bck";

        //Lock the file
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);

        File.Copy(filePath, filePathCopy);
        var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using (var reader = new StreamReader(x))
        {
            content = reader.ReadToEnd();
        }

        r.Close();
        File.Delete(filePathCopy);

当您点击File.Copy行时,此代码崩溃。异常与之前相同:文件正被另一个进程使用。

如果要读取文件,则需要终止具有文件锁定的进程,或者如果您拥有锁定文件的文件的源代码以更改此文件以使用FileShare.ReadWrite而不仅仅是FileShare .WRITE。

答案 2 :(得分:1)

即使文件被锁定,您也可以创建一个副本并读取它。

或者FileStream上的StreamReader可能取决于SQL如何打开文件?

new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);