读取文本文件,然后搜索内存中有效的方式串(并中止发现时)(read a text file and

2019-10-23 00:13发布

我在寻找一个文本文件中的字符串(也包括XML)。 这是我首先想到:

using (StreamReader sr = File.OpenText(fileName))
{
    string s = String.Empty;
    while ((s = sr.ReadLine()) != null)
    {
        if (s.Contains("mySpecialString"))
            return true;
    }
}

return false;

我想逐行读出,以尽量减少内存使用量。 当字符串已经发现它应该退出操作。 我之所以不处理它作为XML是因为它必须被解析,也将消耗需要更多的内存。

另一个简单的实施将

bool found = File.ReadAllText(path).Contains("mySpecialString") ? true : false;

但会读取完整的文件到内存中,这是不是我想要的。 在另一边可能有性能提升。

另外一个会是这样

foreach (string line in File.ReadLines(path))
{
    if (line.Contains("mySpecialString"))
    {
        return true;
    }
}
return false;

但他们中的哪一个(或者你另外一个?)是更多的内存效率?

Answer 1:

您可以使用查询File.ReadLines ,所以它需要,以满足您的查询只读取尽可能多的行。 在Any()当它击中包含您的串线法将停止。

return File.ReadLines(fileName).Any(line => line.Contains("mySpecialString"));


Answer 2:

我也喜欢接受的答案。 也许我在这里很微opimizing事情,但你已经问了内存使用效率的方法。 还要考虑您正在搜索的文本还可以包含像新行字符'\r''\n'"\r\n"和一个大的文件理论上可以含有否定的利益一行ReadLines

所以,你可以使用这个方法:

public static bool FileContainsString(string path, string str, bool caseSensitive = true)
{
     if(String.IsNullOrEmpty(str))
        return false;

    using (var stream = new StreamReader(path))
    while (!stream.EndOfStream)
    {
        bool stringFound = true;
        for (int i = 0; i < str.Length; i++)
        {
            char strChar = caseSensitive ? str[i] : Char.ToUpperInvariant(str[i]);
            char fileChar = caseSensitive ? (char)stream.Read() : Char.ToUpperInvariant((char)stream.Read());
            if (strChar != fileChar)
            {
                stringFound = false;
                break; // break for-loop, start again with first character at next position
            }
        }
        if (stringFound) 
            return true;
    }
    return false;
}

bool containsString = FileContainsString(path, "mySpecialString", false); // ignore case if desired

请注意,这可能是最有效的方法,并隐藏在也可读的方法。 但它有一个缺点,这是不可行的实现文化敏感比较,因为它着眼于单个字符,而不是在子。

所以,你必须保持一些边缘情况记在这里你可以遇到的问题,如著名的土耳其我例子或代理对 。



Answer 3:

我想无论您的解决方案都是一样的。 阅读在MSDN: https://msdn.microsoft.com/en-us/library/dd383503%28v=vs.110%29.aspx

在那里,它说:“方法不同为readlines方法和ReadAllLines如下:当您使用readlines方法,你可以返回整个集合之前开始枚举字符串的集合”

同一篇文章也表明readlines方法应与LINQ到对象一起使用。



文章来源: read a text file and search for string in memory efficient way (and abort when found)