Ejemplo n.º 1
0
        /// <summary>
        /// Поиск строки whatToFind начиная со строки stringNumber и буквы с номером letterNumber
        /// </summary>
        /// <param name="whatToFind">Строка, которую необходимо найти</param>
        /// <param name="stringNumber">Номер строки, начиная с которого надо искать</param>
        /// <param name="letterNumber">Номер буквы в строке stringNumber, начиная с которого надо искать</param>
        /// <param name="returnPosition">Флаг указывающия нужно ли в параметрах stringNumber и letterNumber возвращать позицию найденного вхождения строки whatToFind</param>
        /// <param name="waitCaching">Нужно ли ожидать завершения построения индекса-кеша в том случае, если к моменту вызова он не был ещё достроен</param>
        /// <returns></returns>
        public bool find(string whatToFind, ref long stringNumber, ref int letterNumber, bool returnPosition = false, bool waitCaching = true)
        {
            checkDisposed();
            SubstringPosition [] result = findInternal(whatToFind, stringNumber, letterNumber, waitCaching, 1);

            if ((result.Length > 0) && (returnPosition))
            {
                SubstringPosition sp = _searchCache[whatToFind];
                stringNumber = sp.Item1;
                letterNumber = sp.Item2;
            }
            return(result.Length > 0);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Основной метод для поиска строки в целевом файле. Открытые методы find/findAll должны вызывать эту функци
        /// </summary>
        /// <param name="whatToFind">Строка, которую надо искать</param>
        /// <param name="stringNumber">Номер строки целевого файла, начиная с которой нужно искать</param>
        /// <param name="letterNumber">     Номер позиции в строке, начиная с которой надо искать в строке stringNumber. Во всех строках, номер которых больше, чем stringNumber,
        ///                                 поиск будет осуществляться с нулевой позиции</param>
        /// <param name="waitCaching">Нужно ли ожидать завершения построения индекса-кеша в том случае, если к моменту вызова он не был ещё достроен</param>
        /// <param name="entriesNumber">Сколько вхождений искомой строки нужно вернуть. При значении -1 нужно вернуть все вхождения, которые есть в целевом файле</param>
        /// <returns></returns>
        private SubstringPosition[] findInternal(string whatToFind, long stringNumber, int letterNumber, bool waitCaching = true, long entriesNumber = -1)
        {
            List <SubstringPosition> result = new List <SubstringPosition>();

            bool cacheReady = _waitInitedInternal(waitCaching);

            if (!cacheReady)
            {
                throw new WaitCacheException();
            }

            // Получаем список номеров строк, в котором есть вхождения первых двух буков искомой строки и которые нужно проверить методом IndexOf.
            //              Строки, в которых нет таких вхождений мы проверять не будем
            long[] stringsNumbers   = _cache.getStringNumbers(whatToFind);
            int    stringsNumberPtr = 0; // Указатель на номер в массиве строк в которых есть вхождения первых двух буков строки whatToFind, которую мы будем проверять с помощью IndexOf
            string current;

            // Открываем целевой файл
            using (FileStream fs = new FileStream(_rawPathToFile, FileMode.Open, FileAccess.Read))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    int currentStringNumber = -1;
                    _logger.Clear();
                    _logger.WriteLine("Cache searching process...");
                    // Читаем построчно целевой файл
                    while (!sr.EndOfStream)
                    {
                        currentStringNumber++;
                        current = sr.ReadLine();
                        // Если текущая строка меньше минимального номера строки, которой мы вообще рассматриваем, то не продолжаем итерацию
                        if (currentStringNumber < stringNumber)
                        {
                            continue;
                        }

                        // Прокручиваем указатель stringsNumberPtr до тех пор, пока он не будет указывать на первую строку, номер которой больше, чем номер считанной на данной итерации из целевого файла
                        while (stringsNumbers[stringsNumberPtr] < currentStringNumber)
                        {
                            stringsNumberPtr++;
                            // Если мы достигла конца массива строк с вхождениями, то мы должны выйти из функции - мы больше ничего не найдём
                            if (stringsNumberPtr >= stringsNumbers.Length)
                            {
                                return(result.ToArray());
                            }
                        }
                        // Если номер строки, прочитанной из целевого файла равен номеру из массива строк с вхождениями первых двух буков искомой строки,
                        //        мы должны её обработать и проанализировать есть ли вхождения не только первых двух буков искомой строки, но и всей строки whatToFind
                        if (stringsNumbers[stringsNumberPtr] == currentStringNumber)
                        {
                            // Начинаем с начала строки
                            int currentIndex = -1;
                            // Если строка первая, которую мы рассматрвиаем - то позицию буквы в строке берём из параметра
                            if (currentStringNumber == stringNumber)
                            {
                                currentIndex = letterNumber;
                            }

                            // До тех пор пока есть вхождения искомой строки в строке, прочитанной из файла
                            while ((currentIndex = current.IndexOf(whatToFind, currentIndex + 1)) >= 0)
                            {
                                // Инициализируем структуру с найденной позицией (номер строки, номер буквы)
                                SubstringPosition newPosition = new SubstringPosition(currentStringNumber, currentIndex);

                                // Записываем эту позицию в поисковый кеш, чтобы в следующий раз начать поиск с этой позиции
                                _searchCache[whatToFind] = newPosition;
                                result.Add(newPosition);

                                // Првоеряем сколько позиций вхождения искомой строки нам нужно вернуть и если достаточно - возвращаемся из функции
                                if ((entriesNumber >= 0) && (result.Count == entriesNumber))
                                {
                                    return(result.ToArray());
                                }
                            }
                        }
                    }
                }
            }
            return(result.ToArray());
        }