【问题标题】:C# searching for string in large text file. If you search the same file goto line you last read and start searchC# 在大文本文件中搜索字符串。如果您搜索相同的文件转到您上次阅读的行并开始搜索
【发布时间】:2012-12-15 22:31:46
【问题描述】:

如果我在一天中多次搜索同一个 LOG 文件中的字符串,以某种方式转到上次搜索时读取文件的最后一行然后开始逐行读取会更快吗?这里会节省很多钱吗?

示例文件

进程ID逻辑

11111 在中间层服务器上运行一些愚蠢的逻辑。

11111 仍在运行逻辑

22222 在其他用户的中间层服务器上运行一些愚蠢的逻辑。

11111 哦,看第一个过程完成了。

22222 仍在第二个进程上运行逻辑。

有时我想要从上次加载文件开始的多行文件。目前我使用 UltraEdit 加载文件一次,然后更新文件,但这仍然需要相当长的时间。

在上面的这个例子中,我想从第一个进程开始。

注意:

  1. 文件有时可以达到数百 MB。
  2. 上面的例子是缩略的,每个进程 ID 可能包含 100 行逻辑。
  3. 我正在通过网络访问日志文件。我发现使用 UE 从网络加载文件然后继续更新文件比复制到我的本地 PC 然后打开它更快。
  4. 我希望有一个可以从 powershell 运行的 C# 控制台应用程序,并将我想要的行通过管道传输到屏幕或文件。

我的另一个问题是,怎样才能使这个过程尽可能高效? 1.关于用于我的文件大小的 C# 方法? 2.关于用于编写实用程序的应用程序?我有 powershell、C#、C++、perl

【问题讨论】:

  • 欢迎来到stackoverflow @B8factor,请阅读faqHow to Ask

标签: c# string search


【解决方案1】:

这可以使用 Stream.Seek 实现。您只需要记住流中的最后一个位置是什么,然后从那里继续前进。如果您的日志文件只向其中添加行,这将正常工作,并且肯定会比一遍又一遍地读取和扫描相同的行更快。

如果您发布一些现有代码,我什至可以帮助您编写代码。

http://msdn.microsoft.com/en-us/library/system.io.stream.seek.aspx

【讨论】:

    【解决方案2】:

    我想自己实现这样的东西,所以我花了一些时间试一试。这是我想出的FileStream 的扩展方法(你必须把它放在一个静态类中):

    public static string ReadLineAndCountPosition(this FileStream fs, ref long position)
    {
        //Check if too great a position was passed in:
        if (position > fs.Length)
            return null;
        bool is_carriage_return = false;
        StringBuilder sb = new StringBuilder();
        fs.Seek(position, SeekOrigin.Begin);
    
        while (position < fs.Length)
        {
            var my_byte = fs.ReadByte();
            position++;
            //Check for newlines
            if (is_carriage_return && my_byte == 10)// \n
                return sb.ToString();
            if (my_byte == 13)                     // \r
                is_carriage_return = true;
            else
            {
                is_carriage_return = false;
                sb.Append((char)my_byte);
            }
    
        }
        return sb.ToString();//We've consumed the entire file.
    }
    

    要使用它,您可以使用ReadLineAndCountPosition,只需调用它并传入long 参数,我们将保存该位置。稍后我们将简单地.Seek() 到该位置。

    static void Main(string[] args)
    {
        FileStream fs = new FileStream("testfile.txt",FileMode.Open);
        long saved_position = 0;
    
        while(true)
        {
            string current_line = fs.ReadLineAndCountPosition(ref saved_position);
            if (current_line == null || current_line == "SomeSearchString")
                break;
        }
    
        //Some time later we want to search from the saved position:
        while(true)
        {
            string current_line = fs.ReadLineAndCountPosition(ref saved_position);
            if (current_line == null || current_line == "SecondSearchString")
                break;
        }
    }
    

    我自己进行了一些测试,似乎运行良好。如果您有任何麻烦,请告诉我。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 2013-12-03
      • 2021-03-14
      • 2015-10-15
      • 2010-12-10
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多