如何在不锁定磁盘文件的情况下读取文本文件?

Joa*_*nge 1 .net c# parsing file streamreader

基本上我有一些这样的代码将 ASCII 文本文件的内容读入一个列表:

    List<string> lines = new List<string> ( );
    using ( StreamReader sr = File.OpenText ( textfile ) )
    {
        string s = String.Empty;
        while ( ( s = sr.ReadLine ( ) ) != null )
            lines.Add ( s );
    }
Run Code Online (Sandbox Code Playgroud)

但问题是当另一个线程正在写入文件时,它会引发异常:

该进程无法访问文件“myfile.txt”,因为它正被另一个进程使用。

File.ReadAllLines 也会发生同样的事情。为什么这些函数会锁定磁盘上的文件或关心该文件正在被另一个进程使用?

我只是想定期读取内容,所以如果这次正在使用它,那么下次它将读取更新的内容。我这样做是为了检查是否添加了新条目,因为用户也可以手动添加它们。

我可以使用哪些函数将此文件读入内存而不引发异常,或者我应该使用在 try/catch 中运行此代码。

这是最新的代码:

        var fs = new FileStream ( filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );
        using ( StreamReader sr = new StreamReader ( fs ) )
        {
            string s = String.Empty;
            while ( ( s = sr.ReadLine ( ) ) != null )
                lines.Add ( s );
        }
Run Code Online (Sandbox Code Playgroud)

修改文件的代码:

public static void RemoveCoinFromBuyOrderLogs ( string symbol )
{
    if ( !walletLocked )
    {
        walletLocked = true;

        string [ ] lines = File.ReadAllLines ( walletFilename );

        var newlines = lines.Where ( c => !c.StartsWith ( symbol + "USDT" ) && !c.StartsWith ( symbol + "BUSD" ) && !c.StartsWith ( symbol + "USDC" ) && !c.StartsWith ( symbol + "TUSD" ) ).Select ( c => c ).ToList ( );
        File.WriteAllLines ( walletFilename, newlines );

        using ( FileStream fs = File.Open ( walletFilename, FileMode.OpenOrCreate ) )
        {
            StreamWriter sw = new StreamWriter ( fs );
            sw.AutoFlush = true;
            newlines.ForEach ( r => sw.WriteLine ( r ) );
        }

        walletLocked = false;
    }
}

public static void AddCoinToOrderLogs ( string newOrder, long orderId )
{
    if ( !walletLocked )
    {
        var lines = Utility.ReadAllLines ( walletFilename );
        lines = lines.Select ( line => line.Replace ( "\r", "" ) ).ToList ( );
        lines = lines.Where ( line => line != "" ).Select ( line => line ).ToList ( );

        var fields = lines.Select ( line => line.Split ( '\t' ) ).ToList ( );

        bool duplicate = false;
        foreach ( var field in fields )
        {
            if ( field.Length >= 5 )
            {
                long id = Convert.ToInt64 ( field [ 4 ] );
                if ( id == orderId )
                    duplicate = true;
            }
        }

        if ( !duplicate )
        {
            lines.Add ( newOrder );
            lines.Sort ( );

            walletLocked = true;
            File.WriteAllLines ( walletFilename, lines );
            walletLocked = false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

mu8*_*u88 5

看看这个超负荷File.Open()。它允许您指定附加参数以避免锁定。我认为它应该可以解决问题。

例如,你可以做 var stream = new FileStream(textfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);