从txt中的500k条目中搜索字符串

时间:2012-02-21 16:17:48

标签: c# c#-4.0

我有一个.txt文件,其中有大约500个条目,每个条目用新行分隔。文件大小约为13MB,每行的格式如下:

SomeText<tab>Value<tab>AnotherValue<tab>

我的问题是从程序的输入中找到某个“字符串”,从文件的第一列开始,并从两列中获取相应的ValueAnotherValue

第一列未排序,但文件中的secondthird列值实际上已排序。但是,这种排序对我来说没什么用处。

该文件是静态的,不会更改。我想在这里使用Regex.IsMatch(),但我不确定这是否是最好的方法,一行一行。

如果查找时间会急剧增加,我可能会重新排列第一列(因此会对second&amp; third列进行排序。如果需要,有关如何实施此方法或上述方法的任何建议吗?

找到字符串后,我应该如何获取这两个列值?

修改 我意识到文件中会有相当多的搜索对用户的至少oe请求。如果我要找到一个值数组,如何返回某种具有相应匹配值的字典?

5 个答案:

答案 0 :(得分:1)

也许使用此代码:

var myLine = File.ReadAllLines()
   .Select(line => line.Split(new [] {' ', '\t'}, SplitStringOptions.RemoveEmptyEntries)
   .Single(s => s[0] == "string to find");

myLine是一个表示行的字符串数组。您还可以使用.AsParallel()扩展方法来获得更好的性能。

答案 1 :(得分:0)

var firstFoundLine = File.ReadLines("filename").FirstOrDefault(s => s.StartsWith("string"));
if (firstFoundLine != "")
{
    char yourColumnDelimiter = '\t';
    var columnValues = firstFoundLine.Split(new []{yourColumnDelimiter});
    var secondColumn = columnValues[1];
    var thirdColumns = columnValues[2];
}

File.ReadLines优于File.RealAllLines因为您不需要读取整个文件 - 只有在找到匹配的字符串http://msdn.microsoft.com/en-us/library/dd383503.aspx

之后

答案 2 :(得分:0)

将这种怪物解析为某种数据库 SQL Server / MySQL是首选,但如果由于各种原因无法使用它们,SQLite甚至Access或Excel都可以使用。 这样做一次并不难 完成后,搜索将变得简单快捷。

答案 3 :(得分:0)

GetLines(inputPath).FirstOrDefault(p=>p.Split(",")[0]=="SearchText")

private static IEnumerable<string> GetLines(string inputFile)
{
    string filePath = Path.Combine(Directory.GetCurrentDirectory(),inputFile);
    return File.ReadLines(filePath);
}

答案 4 :(得分:0)

您需要多少次进行此搜索?   如果您节省每次搜索的时间,那么启动时的某些预处理成本是否值得?   是否可以在启动时将所有数据加载到内存中?   将文件解析为对象并将结果粘贴到哈希表中?

我认为Regex不会比任何标准字符串选项更有帮助。你正在寻找一个固定的字符串值,而不是一个模式,但我仍然需要纠正。

<强>更新 假设“SomeText”是唯一的,您可以使用像这样的字典

数据表示来自文件的值。 MyData 是一个将它们保存在内存中的类。

public IEnumerable<string> Data = new List<string>() {
  "Text1\tValue1\tAnotherValue1\t",
  "Text2\tValue2\tAnotherValue2\t",
  "Text3\tValue3\tAnotherValue3\t",
  "Text4\tValue4\tAnotherValue4\t",
  "Text5\tValue5\tAnotherValue5\t",
  "Text6\tValue6\tAnotherValue6\t",
  "Text7\tValue7\tAnotherValue7\t",
  "Text8\tValue8\tAnotherValue8\t"
};

public class MyData {
   public String SomeText { get; set; }
   public String Value { get; set; }
   public String AnotherValue { get; set; }
}


[TestMethod]
public void ParseAndFind() {

        var dictionary = Data.Select(line =>
        {
            var pieces = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
            return new MyData {
                SomeText = pieces[0],
                Value = pieces[1],
                AnotherValue = pieces[2],
            };
        }).ToDictionary<MyData, string>(dat =>dat.SomeText);

        Assert.AreEqual("AnotherValue3", dictionary["Text3"].AnotherValue);
        Assert.AreEqual("Value7", dictionary["Text7"].Value);

}

hth,

艾伦