Поиск строки из 500 000 записей в TXT - PullRequest
0 голосов
/ 21 февраля 2012

У меня есть файл .txt, в котором содержится около 500 тыс. Записей, каждая из которых разделена новой строкой. Размер файла составляет около 13 МБ, а формат каждой строки следующий:

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

Моя проблема состоит в том, чтобы найти определенную «строку» с входными данными программы из первого столбца в файле и получить соответствующие Value и AnotherValue из двух столбцов.

Первый столбец не отсортирован, но значения столбцов second и third в файле фактически отсортированы. Но эта сортировка бесполезна для меня.

Файл статичен и не изменяется. Я думал использовать Regex.IsMatch() здесь, но я не уверен, что это лучший подход здесь, чтобы идти строка за строкой.

Если бы время поиска резко увеличилось, я мог бы, вероятно, перейти к перестановке первого столбца (и, следовательно, к сортировке столбца second & third). Любые предложения о том, как реализовать этот подход или вышеупомянутый подход, если требуется?

Как найти строку, как найти строку?

EDIT Я понял, что в файле будет довольно много поисков, по крайней мере, по запросу пользователя. Если у меня есть массив значений, которые нужно найти, как я могу вернуть какой-то словарь, имеющий соответствующие значения найденных совпадений?

Ответы [ 5 ]

1 голос
/ 21 февраля 2012

Может быть с этим кодом:

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

myLine - это массив строк, представляющий строку.Вы также можете использовать .AsParallel() метод расширения для лучшей производительности.

0 голосов
/ 21 февраля 2012

Сколько раз вам нужно сделать этот поиск?
Стоит ли платить за предварительную обработку при запуске, если вы экономите время на каждом поиске? Возможна ли загрузка всех данных в память при запуске? Разобрать файл в объекты и вставить результаты в хеш-таблицу?

Я не думаю, что 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);

}

чч,

Alan

0 голосов
/ 21 февраля 2012
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);
}
0 голосов
/ 21 февраля 2012

Разобрать это чудовище в какую-то базу данных.
SQL Server / MySQL предпочтительнее, но если вы не можете использовать их по разным причинам, SQLite или даже Access или Excel могут работать. Делать это один раз не сложно.
После того, как вы закончите, поиск станет легким и быстрым.

0 голосов
/ 21 февраля 2012
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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...