예제 #1
0
        private WorkerItem ModifiedLogFile()
        {
            SetStatus("Parser.ModifiedLogFile:enter");
            List <IFile <LogFileItem> > currentLogFiles = CurrentLogFiles();
            LogFile currentLogFile = CurrentLogFile();

            if (currentLogFiles == null) // || currentLogFile == null)
            {
                SetStatus("Parser.ModifiedLogFile:currentLog empty");
                // SyncLogFiles();
                return(new WorkerItem());
            }

            if (_previousLogFiles.Count == currentLogFiles.Count)
            {
                WorkerItem workerItem = new WorkerItem()
                {
                    FilterFile         = (FilterFile)_filterViewModel.CurrentFile(),
                    LogFile            = currentLogFile,
                    WorkerModification = WorkerItem.Modification.Unknown,
                    FilterNeed         = FilterNeed.Current
                };

                if (currentLogFile != _logFilePrevious)
                {
                    workerItem.WorkerModification = WorkerItem.Modification.LogIndex;
                    workerItem.FilterNeed         = FilterNeed.Filter;
                    _logFilePrevious = currentLogFile;
                }

                SetStatus("Parser.ModifiedLogFile:logfile count same");
                return(workerItem);
            }
            else if (_previousLogFiles.Count < currentLogFiles.Count)
            {
                SetStatus("Parser.ModifiedLogFiles:logfile file added");
                SyncLogFiles();
                return(new WorkerItem()
                {
                    LogFile = CurrentLogFile(),
                    FilterNeed = FilterNeed.Filter,
                    WorkerModification = WorkerItem.Modification.LogAdded
                });
            }
            else
            {
                SetStatus("Parser.ModifiedLogFiles:logfile file removed");
                SyncLogFiles();
                return(new WorkerItem()
                {
                    LogFile = CurrentLogFile(),
                    FilterNeed = FilterNeed.Filter,
                    WorkerModification = WorkerItem.Modification.LogRemoved
                });
            }

            //return new WorkerItem()
            //{
            //    FilterNeed = FilterNeed.Unknown,
            //    WorkerModification = WorkerItem.Modification.Unknown
            //};
        }
예제 #2
0
        public ObservableCollection <LogFileItem> ApplyFilter(LogTabViewModel logTab, LogFile logFile, List <FilterFileItem> filterFileItems, FilterCommand filterCommand)
        {
            Mouse.OverrideCursor = Cursors.Wait;
            DateTime timer = DateTime.Now;

            SetStatus(string.Format("ApplyFilter:start time: {0} log file: {1} ", timer.ToString("hh:mm:ss.fffffff"), logFile.Tag));

            List <FilterFileItem> filterItems = VerifyFilterPatterns(filterFileItems, logTab);

            Debug.Print(string.Format("ApplyFilter: filterItems.Count={0}:{1}", Thread.CurrentThread.ManagedThreadId, filterItems.Count));

            // set regex cache size to number of filter items for better performance
            // https: //msdn.microsoft.com/en-us/library/gg578045(v=vs.110).aspx
            Regex.CacheSize = filterItems.Count;

            int inclusionFilterCount = filterItems.Count(x => x.Include == true);

            ParallelOptions po = new ParallelOptions
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount // / 2
            };

            try
            {
                Parallel.ForEach(logFile.ContentItems, po, logItem =>
                {
                    if (string.IsNullOrEmpty(logItem.Content))
                    {
                        Debug.Print(string.Format("ApplyFilter: logItem.Content empty={0}:{1}", Thread.CurrentThread.ManagedThreadId, logItem.Content));
                        // used for goto line as it needs all line items
                        logItem.FilterIndex = int.MinValue;
                        return;
                    }

                    int filterIndex    = int.MaxValue; // int.MinValue;
                    int includeFilters = inclusionFilterCount;

                    if (Settings.CountMaskedMatches)
                    {
                        logItem.Masked = new int[filterItems.Count, 1];
                    }

                    // clear out groups
                    logItem.Group1 = string.Empty;
                    logItem.Group2 = string.Empty;
                    logItem.Group3 = string.Empty;
                    logItem.Group4 = string.Empty;

                    bool matchSet = false;

                    for (int fItem = 0; fItem < filterItems.Count; fItem++)
                    {
                        int filterItemIndex       = filterFileItems[fItem].Index;
                        bool match                = false;
                        FilterFileItem filterItem = filterItems[fItem];
                        Debug.Print(string.Format("ApplyFilter: loop:{0} filterItem.Pattern={1}:{2} logItem.Content:{3}", filterItemIndex,
                                                  Thread.CurrentThread.ManagedThreadId, filterItem.Filterpattern, logItem.Content));

                        // unnamed and named groups
                        //if (logTab.GroupCount > 0 && filterItem.Regex)
                        if (filterItem.GroupCount > 0 && filterItem.Regex)
                        {
                            MatchCollection mc = Regex.Matches(logItem.Content, filterItem.Filterpattern, RegexOptions.Singleline | (filterItem.CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase));
                            if (mc.Count > 0)
                            {
                                match = true;

                                foreach (Match m in mc)
                                {
                                    if (!string.IsNullOrEmpty(m.Groups[1].Value.ToString()))
                                    {
                                        logItem.Group1 += (string.IsNullOrEmpty(logItem.Group1) ? "" : ";\n") + m.Groups[1].Value.ToString();
                                    }

                                    if (!string.IsNullOrEmpty(m.Groups[2].Value.ToString()))
                                    {
                                        logItem.Group2 += (string.IsNullOrEmpty(logItem.Group2) ? "" : ";\n") + m.Groups[2].Value.ToString();
                                    }

                                    if (!string.IsNullOrEmpty(m.Groups[3].Value.ToString()))
                                    {
                                        logItem.Group3 += (string.IsNullOrEmpty(logItem.Group3) ? "" : ";\n") + m.Groups[3].Value.ToString();
                                    }

                                    if (!string.IsNullOrEmpty(m.Groups[4].Value.ToString()))
                                    {
                                        logItem.Group4 += (string.IsNullOrEmpty(logItem.Group4) ? "" : ";\n") + m.Groups[4].Value.ToString();
                                    }
                                }
                            }
                        }
                        else if (filterItem.Regex && Regex.IsMatch(logItem.Content, filterItem.Filterpattern, RegexOptions.Singleline | (filterItem.CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase)))
                        {
                            match = true;
                        }
                        else if (!filterItem.Regex)
                        {
                            bool andMatch = true;
                            if (filterItem.StringOperators)
                            {
                                Debug.Print(string.Format("ApplyFilter: loop:{0} string with operators "
                                                          + "thread id:{1} filter index:{2} filter string: {3}",
                                                          filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId,
                                                          filterIndex,
                                                          filterItem.Filterpattern));
                                // check for ' AND ' and ' OR ' operators
                                foreach (string andPattern in Regex.Split(filterItem.Filterpattern, " AND "))
                                {
                                    Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern "
                                                              + "thread id:{1} filter index:{2} filter string: {3}",
                                                              filterItemIndex,
                                                              Thread.CurrentThread.ManagedThreadId,
                                                              filterIndex,
                                                              andPattern));

                                    match        = false;
                                    string[] ors = Regex.Split(andPattern, " OR ");
                                    if (ors.Length > 1)
                                    {
                                        foreach (string orPattern in ors)
                                        {
                                            Debug.Print(string.Format("ApplyFilter: loop:{0} string orPattern "
                                                                      + "thread id:{1} filter index:{2} filter string: {3}",
                                                                      filterItemIndex,
                                                                      Thread.CurrentThread.ManagedThreadId,
                                                                      filterIndex,
                                                                      orPattern));
                                            // only match one
                                            if (filterItem.CaseSensitive && logItem.Content.Contains(orPattern))
                                            {
                                                match = true;
                                                Debug.Print(string.Format("ApplyFilter: loop:{0} string orPattern match "
                                                                          + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                          filterItemIndex,
                                                                          Thread.CurrentThread.ManagedThreadId,
                                                                          filterIndex,
                                                                          orPattern,
                                                                          logItem.Content));
                                                break;
                                            }
                                            else if (logItem.Content.ToLower().Contains(orPattern.ToLower()))
                                            {
                                                match = true;
                                                Debug.Print(string.Format("ApplyFilter: loop:{0} string orPattern match "
                                                                          + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                          filterItemIndex,
                                                                          Thread.CurrentThread.ManagedThreadId,
                                                                          filterIndex,
                                                                          orPattern,
                                                                          logItem.Content));
                                                break;
                                            }
                                            else
                                            {
                                                Debug.Print(string.Format("ApplyFilter: loop:{0} string orPattern NO match "
                                                                          + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                          filterItemIndex,
                                                                          Thread.CurrentThread.ManagedThreadId,
                                                                          filterIndex,
                                                                          orPattern,
                                                                          logItem.Content));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // match all
                                        if (filterItem.CaseSensitive && logItem.Content.Contains(andPattern))
                                        {
                                            match = true;
                                            Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern all match "
                                                                      + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                      filterItemIndex,
                                                                      Thread.CurrentThread.ManagedThreadId,
                                                                      filterIndex,
                                                                      andPattern,
                                                                      logItem.Content));
                                        }
                                        else if (logItem.Content.ToLower().Contains(andPattern.ToLower()))
                                        {
                                            match = true;
                                            Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern all match "
                                                                      + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                      filterItemIndex,
                                                                      Thread.CurrentThread.ManagedThreadId,
                                                                      filterIndex,
                                                                      andPattern,
                                                                      logItem.Content));
                                        }
                                        else
                                        {
                                            Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern all NO match "
                                                                      + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                                      filterItemIndex,
                                                                      Thread.CurrentThread.ManagedThreadId,
                                                                      filterIndex,
                                                                      andPattern,
                                                                      logItem.Content));
                                        }
                                    }

                                    andMatch &= match;
                                }

                                match = andMatch;
                            }
                            else
                            {
                                // normal string match
                                if (filterItem.CaseSensitive && logItem.Content.Contains(filterItem.Filterpattern))
                                {
                                    match = true;
                                    Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern one match "
                                                              + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                              filterItemIndex,
                                                              Thread.CurrentThread.ManagedThreadId,
                                                              filterIndex,
                                                              filterItem.Filterpattern,
                                                              logItem.Content));
                                }
                                else if (logItem.Content.ToLower().Contains(filterItem.Filterpattern.ToLower()))
                                {
                                    match = true;
                                    Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern one match "
                                                              + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                              filterItemIndex,
                                                              Thread.CurrentThread.ManagedThreadId,
                                                              filterIndex,
                                                              filterItem.Filterpattern,
                                                              logItem.Content));
                                }
                                else
                                {
                                    Debug.Print(string.Format("ApplyFilter: loop:{0} string andPattern one NO match "
                                                              + "thread id:{1} filter index:{2} filter string: {3} logItem content: {4}",
                                                              filterItemIndex,
                                                              Thread.CurrentThread.ManagedThreadId,
                                                              filterIndex,
                                                              filterItem.Filterpattern,
                                                              logItem.Content));
                                }
                            }
                        }

                        Debug.Print(string.Format("ApplyFilter:** loop:{0} filterItem Match={1}:{2} **", filterItemIndex, Thread.CurrentThread.ManagedThreadId, match));

                        if (!matchSet)
                        {
                            if (match && filterItem.Include && !filterItem.Exclude)
                            {
                                filterIndex = filterItemIndex;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} filterItem.Include not exclude setting filterIndex={1}:{2}", filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId, filterIndex));
                                matchSet = true;
                                includeFilters--;
                                // break;
                            }
                            else if (!match && filterItem.Include && filterItem.Exclude)
                            {
                                // dynamic filter with and quickfindand but no match so exit
                                filterIndex = int.MinValue;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} no match filterItem.Include and exclude setting filterIndex={1}:{2}", filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId, filterIndex));
                                matchSet       = true;
                                includeFilters = 0;
                                // break;
                            }
                            else if (match && filterItem.Include && filterItem.Exclude)
                            {
                                // dynamic filter with and quickfindand but with match
                                filterIndex = int.MinValue;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} match filterItem.Include and exlude setting filterIndex={1}:{2}", filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId, filterIndex));
                                matchSet       = false;
                                includeFilters = 0;
                                // break;
                            }
                            else if (match && filterItem.Exclude)
                            {
                                filterIndex = (fItem * -1) - 2;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} filterItem.Exclude and match filterIndex={1}:{2}", filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId, filterIndex));

                                matchSet = true;
                                // break;
                            }
                            else if (!match && !filterItem.Exclude)
                            {
                                filterIndex = int.MinValue;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} not filterItem.Exclude and not match filterIndex={1}:{2}",
                                                          filterItemIndex, Thread.CurrentThread.ManagedThreadId, filterIndex));
                            }
                            else if (match)
                            {
                                filterIndex = filterItemIndex;
                                Debug.Print(string.Format("ApplyFilter: loop:{0} setting filterIndex={1}:{2}", filterItemIndex,
                                                          Thread.CurrentThread.ManagedThreadId, filterIndex));
                                matchSet = true;
                                // break;
                            }
                            else if (filterItem.Include)
                            {
                                includeFilters--;
                            }
                        }
                        else if (matchSet && match && Settings.CountMaskedMatches)
                        {
                            logItem.Masked[fItem, 0] = 1;
                            Debug.Print(string.Format("ApplyFilter: loop:{0} masked match filterIndex={1}:{2}", filterItemIndex,
                                                      Thread.CurrentThread.ManagedThreadId, filterItemIndex));
                        }

                        if (matchSet && !Settings.CountMaskedMatches)
                        {
                            Debug.Print(string.Format("ApplyFilter: loop:{0} not filterItem.Exclude CountMaskedMatches={1}:{2}", filterItemIndex,
                                                      Thread.CurrentThread.ManagedThreadId, Settings.CountMaskedMatches));

                            if (includeFilters == 0)
                            {
                                break;
                            }
                        }
                    }

                    Debug.Print(string.Format("ApplyFilter: loop finished set filterIndex={0}:{1}", Thread.CurrentThread.ManagedThreadId, filterIndex));
                    logItem.FilterIndex = filterIndex;
                });

                // write totals negative indexes arent displayed and are only used for counting
                int filterCount = 0;
                for (int i = 0; i < filterFileItems.Count; i++)
                {
                    int filterItemIndex = filterFileItems[i].Index;
                    filterFileItems[i].Count = logFile.ContentItems.Count(x => x.FilterIndex == filterItemIndex | x.FilterIndex == (i * -1) - 2);

                    if (Settings.CountMaskedMatches)
                    {
                        filterFileItems[i].MaskedCount = logFile.ContentItems.Count(x => (x.FilterIndex != int.MaxValue) & (x.FilterIndex != int.MinValue) && x.Masked[i, 0] == 1);
                        SetStatus(string.Format("ApplyFilter:filterItem masked counttotal: {0}", filterFileItems[i].MaskedCount));
                    }

                    SetStatus(string.Format("ApplyFilter:filterItem counttotal: {0}", filterFileItems[i].Count));

                    filterCount += filterFileItems[i].Count;
                }

                double totalSeconds = DateTime.Now.Subtract(timer).TotalSeconds;
                SetStatus(string.Format("ApplyFilter:total time in seconds: {0}\n\tlines per second: {1} "
                                        + "\n\tlogfile total lines count: {2}\n\tlogfile filter lines count: {3}\n\tlog file: {4}"
                                        + "\n\tnumber of filters: {5}\n\tcalculated lines per second for single query: {6}",
                                        totalSeconds,
                                        logFile.ContentItems.Count / totalSeconds,
                                        logFile.ContentItems.Count,
                                        filterCount,
                                        logFile.Tag,
                                        filterItems.Count,
                                        logFile.ContentItems.Count / totalSeconds * filterItems.Count));

                Mouse.OverrideCursor = null;
                return(new ObservableCollection <LogFileItem>(logFile.ContentItems.Where(x => x.FilterIndex > -2)));
            }
            catch (Exception e)
            {
                SetStatus("ApplyFilter:exception" + e.ToString());
                Mouse.OverrideCursor = null;
                return(new ObservableCollection <LogFileItem>());
            }
        }
예제 #3
0
        public LogFile MMFConcurrentRead(LogFile logFile, BackgroundWorker backgroundWorker)
        {
            Debug.Print("MMFConcurrentRead: enter");
            GetEncoding(logFile);
            // not sure why this here. messing up temp file
            //logFile.IsNew = false;
            //logFile.Modified = false;

            if (!File.Exists(logFile.Tag))
            {
                Debug.Print("MMFConcurrentRead:error, file does not exist: " + logFile.Tag);
                return(logFile);
            }

            byte[] bytes = new byte[new FileInfo(logFile.Tag).Length];
            // 4,8,12
            int threadCount = 1;

            if (bytes.Length > 1000000)
            {
                threadCount = 8;
            }

            int bposition = logFile.HasBom ? logFile.Encoding.GetPreamble().Length : 0;
            int blen      = bytes.Length / threadCount;

            MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(logFile.Tag, FileMode.Open, "mmf", bytes.Length, MemoryMappedFileAccess.Read);

            ManualResetEvent[]         completedEvents = new ManualResetEvent[threadCount];
            List <List <LogFileItem> > list            = new List <List <LogFileItem> >();

            for (int i = 0; i < threadCount; i++)
            {
                list.Add(new List <LogFileItem>());
                completedEvents[i] = new ManualResetEvent(false);
            }

            for (int mmfCount = 0; mmfCount < threadCount; mmfCount++)
            {
                if (mmfCount != 0)
                {
                    bposition += blen;
                }

                if (mmfCount == threadCount - 1)
                {
                    blen = bytes.Length - bposition;
                }

                TaskMMFInfo taskInfo = new TaskMMFInfo()
                {
                    mmf            = memoryMappedFile,
                    stringList     = list[mmfCount],
                    logFile        = logFile,
                    position       = bposition,
                    length         = blen,
                    completedEvent = completedEvents[mmfCount],
                    bgWorker       = backgroundWorker
                };

                ThreadPool.QueueUserWorkItem(new WaitCallback(ParallelMMFRead), taskInfo);
            }

            Debug.Print(string.Format("mmf thread length: {0}", blen));

            WaitHandle.WaitAll(completedEvents);

            if (memoryMappedFile != null)
            {
                memoryMappedFile.Dispose();
            }

            if (backgroundWorker.CancellationPending)
            {
                Debug.Print("MMFConcurrentRead:cancelled");
                return(logFile);
            }

            bool patch = false;

            List <LogFileItem> finalList = new List <LogFileItem>();

            for (int listCount = 0; listCount < threadCount; listCount++)
            {
                if (patch)
                {
                    // merge last line with first line in current list
                    finalList[finalList.Count - 1].Content = finalList[finalList.Count - 1].Content + list[listCount][0].Content;
                    list[listCount].RemoveAt(0);
                    patch = false;
                }

                finalList.AddRange(list[listCount]);
                list[listCount].Clear();

                // need to check for partial lines look in last index for needsPatch string
                if (finalList.Count > 0)
                {
                    if (finalList[finalList.Count - 1].Content == _needsPatch)
                    {
                        finalList.RemoveAt(finalList.Count - 1);
                        patch = true;
                    }
                    else
                    {
                        patch = false;
                    }
                }
            }

            // set index
            int counter = 1;

            foreach (LogFileItem item in finalList)
            {
                item.Index = counter++;
            }

            Debug.Print("MMFConcurrentRead:exit");

            logFile.ContentItems = new ObservableCollection <LogFileItem>(finalList);

            return(logFile);
        }
예제 #4
0
        public override IFile <LogFileItem> ReadFile(string fileName)
        {
            // BOM UTF - 8 0xEF,0xBB,0xBF BOM UTF - 16 FE FF NO BOM assume ansi but utf-8 doesnt have
            // to have one either

            LogFile logFile = new LogFile();

            try
            {
                SetStatus("ReadFile:enter: " + fileName);
                Encoding encoding = Encoding.Default;

                logFile.FileName = Path.GetFileName(fileName);
                // find bom
                using (System.IO.StreamReader sr = new System.IO.StreamReader(fileName, true))
                {
                    encoding = sr.CurrentEncoding;

                    SetStatus("current encoding:" + encoding.EncodingName);

                    while (!sr.EndOfStream)
                    {
                        // if bom not supplied, try to determine utf-16 (unicode)
                        string line    = sr.ReadLine();
                        byte[] bytes   = Encoding.UTF8.GetBytes(line);
                        string newLine = Encoding.UTF8.GetString(bytes).Replace("\0", "");
                        SetStatus(string.Format("check encoding: bytes:{0} string: {1}", bytes.Length, newLine.Length));

                        if (bytes.Length > 0 && newLine.Length > 0 &&
                            ((bytes.Length - newLine.Length) * 2 - 1 == bytes.Length
                             | (bytes.Length - newLine.Length) * 2 == bytes.Length))
                        {
                            SetStatus(string.Format("new encoding:Unicode bytes:{0} string: {1}", bytes.Length, newLine.Length));

                            encoding = Encoding.Unicode;
                            break;
                        }
                        else if (bytes.Length > 0 && newLine.Length > 0)
                        {
                            break;
                        }
                    }
                }

                // todo: use mapped file only for large files?

                string[] lines = File.ReadAllLines(fileName, encoding);
                ConcurrentBag <LogFileItem> cLogFileItems = new ConcurrentBag <LogFileItem>();

                Parallel.For(0, lines.Length, x =>
                {
                    LogFileItem logFileItem = new LogFileItem()
                    {
                        Content    = lines[x],
                        Background = Settings.BackgroundColor,
                        Foreground = Settings.ForegroundColor,
                        Index      = x + 1
                    };

                    cLogFileItems.Add(logFileItem);
                });

                logFile.ContentItems = new ObservableCollection <LogFileItem>(cLogFileItems.OrderBy(x => x.Index));
                SetStatus("ReadFile:exit: " + fileName);
                logFile.IsNew = false;
                return(logFile);
            }
            catch (Exception e)
            {
                SetStatus("Fatal:ReadFile:exception: " + e.ToString());
                return(logFile);
            }
        }
예제 #5
0
        private bool GetEncoding(LogFile logFile)
        {
            logFile.HasBom   = false;
            logFile.Encoding = Encoding.GetEncoding("ISO-8859-1"); // extended ascii

            try
            {
                // ascii will be default as it never has bom if all fail utf-7 rarely used and does
                // not have preamble. wiki says 2b,2f,76,variable
                SetStatus("GetEncoding:enter: " + logFile.Tag);

                Encoding[] encodings = new Encoding[] { Encoding.UTF32, Encoding.UTF8, Encoding.BigEndianUnicode, Encoding.Unicode };

                //logFile.FileName = Path.GetFileName(fileName);
                // find bom
                bool foundEncoding = false;

                using (System.IO.StreamReader sr = new System.IO.StreamReader(logFile.Tag, true))
                {
                    // encoding = sr.CurrentEncoding;

                    SetStatus("current encoding:" + logFile.Encoding.EncodingName);
                    // biggest preamble is 4 bytes
                    if (sr.BaseStream.Length < 4)
                    {
                        return(true);
                    }

                    int[] srBytes = new int[4];
                    for (int c = 0; c < srBytes.Length; c++)
                    {
                        srBytes[c] = sr.BaseStream.ReadByte();
                    }

                    sr.DiscardBufferedData();

                    foreach (Encoding enc in encodings)
                    {
                        byte[] bytes = enc.GetPreamble();
                        for (int i = 0; i < bytes.Length; i++)
                        {
                            if (bytes[i] != srBytes[i])
                            {
                                foundEncoding = false;
                                break;
                            }
                            else
                            {
                                foundEncoding = true;
                            }
                        }

                        if (foundEncoding)
                        {
                            logFile.HasBom   = true;
                            logFile.Encoding = enc;
                            return(true);
                        }
                    }

                    // if bom not supplied, try to determine utf-16 (unicode)

                    while (!sr.EndOfStream)
                    {
                        string line    = sr.ReadLine();
                        byte[] bytes   = Encoding.UTF8.GetBytes(line);
                        string newLine = Encoding.UTF8.GetString(bytes).Replace("\0", "");
                        SetStatus(string.Format("check encoding: bytes:{0} string: {1}", bytes.Length, newLine.Length));

                        if (bytes.Length > 0 && newLine.Length > 0 &&
                            ((bytes.Length - newLine.Length) * 2 - 1 == bytes.Length
                             | (bytes.Length - newLine.Length) * 2 == bytes.Length))
                        {
                            SetStatus(string.Format("new encoding:Unicode bytes:{0} string: {1}", bytes.Length, newLine.Length));
                            logFile.Encoding = Encoding.Unicode;

                            SetStatus("new encoding:" + logFile.Encoding.EncodingName);
                            break;
                        }
                        else if (bytes.Length > 0 && newLine.Length > 0)
                        {
                            break;
                        }
                    }
                }
                return(true);
            }
            catch (Exception e)
            {
                SetStatus("Exception:GetEncoding:" + e.ToString());
                return(false);
            }
        }