Пример #1
0
        public bool Exists(string filePath, long expectedFileSize, byte[] expectedHash)
        {
            filePath = NormalizeAndEvaluate(filePath);

            var info = _filesystem.GetFileInfo(filePath);

            if (!info.Exists)
            {
                Log.DebugFormat("The file '{0}' does not exist", filePath);
                return(false);
            }

            if (info.Length != expectedFileSize)
            {
                Log.DebugFormat("The file '{0}' exists, but has a different '{1}' filesize than the expected '{2}'",
                                filePath, info.Length, expectedFileSize);
                return(false);
            }

            var hash = HashCodeCalculator.MD5(filePath);

            if (!HashCodeCalculator.AreEqual(hash, expectedHash))
            {
                Log.DebugFormat(
                    "The file '{0}' exists, has the expected size '{1}', but it's hash '{2}' differs from the expected one '{3}'",
                    filePath,
                    info.Length,
                    HashCodeCalculator.ToString(hash),
                    HashCodeCalculator.ToString(expectedHash));
                return(false);
            }

            Log.DebugFormat(
                "The file '{0}' exists, has the expected size '{1}' and hash '{2}'",
                filePath,
                info.Length,
                HashCodeCalculator.ToString(hash));
            return(true);
        }
Пример #2
0
        public static FileFingerprint FromFile(IFilesystem filesystem, string fileName)
        {
            var info = filesystem.GetFileInfo(fileName);

            return(new FileFingerprint(fileName, info.CreationTimeUtc, info.LastWriteTimeUtc, info.Length));
        }
Пример #3
0
        /// <inheritdoc />
        protected override TimeSpan RunOnce(CancellationToken token)
        {
            bool read = false;

            try
            {
                if (!_filesystem.FileExists(_fileName))
                {
                    SetDoesNotExist();
                }
                else
                {
                    var info     = _filesystem.GetFileInfo(_fileName);
                    var fileSize = info.Length;
                    _localProperties.SetValue(Core.Properties.LastModified, info.LastWriteTimeUtc);
                    _localProperties.SetValue(Core.Properties.Created, info.CreationTimeUtc);
                    _localProperties.SetValue(Core.Properties.Size, Size.FromBytes(fileSize));
                    UpdatePercentageProcessed(_lastStreamPosition, fileSize, allow100Percent: true);
                    SynchronizePropertiesWithUser();

                    using (var stream = _filesystem.Open(_fileName,
                                                         FileMode.Open,
                                                         FileAccess.Read,
                                                         FileShare.ReadWrite))
                    {
                        using (var reader = new StreamReaderEx(stream, _encoding))
                        {
                            // We change the error flag explicitly AFTER opening
                            // the stream because that operation might throw if we're
                            // not allowed to access the file (in which case a different
                            // error must be set).

                            _localProperties.SetValue(Core.Properties.EmptyReason, null);
                            if (stream.Length >= _lastStreamPosition)
                            {
                                stream.Position = _lastStreamPosition;
                            }
                            else
                            {
                                OnReset(stream, out _numberOfLinesRead, out _lastStreamPosition);
                            }

                            int    numProcessed = 0;
                            string currentLine;
                            while ((currentLine = reader.ReadLine()) != null)
                            {
                                token.ThrowIfCancellationRequested();

                                bool lastLineHadNewline = _lastLineHadNewline;
                                var  trimmedLine        = currentLine.TrimNewlineEnd(out _lastLineHadNewline);
                                var  entryCount         = _entries.Count;
                                if (entryCount > 0 && !lastLineHadNewline)
                                {
                                    // We need to remove the last line and create a new line
                                    // that consists of the entire content.
                                    RemoveLast();
                                    trimmedLine        = _untrimmedLastLine + trimmedLine;
                                    _untrimmedLastLine = _untrimmedLastLine + currentLine;
                                }
                                else
                                {
                                    _untrimmedLastLine = currentLine;
                                    ++_numberOfLinesRead;
                                    read = true;
                                }

                                Add(trimmedLine,
                                    _numberOfLinesRead);

                                if (++numProcessed % 1000 == 0)
                                {
                                    // Here's the deal: Since we're processing the file in chunks, we advance the underlying
                                    // stream faster than we're actually consuming lines. This means that it's quite likely
                                    // that at the end of the file, we have moved the stream to the end, but have not quite
                                    // yet processed the underlying buffer from StreamReaderEx. The percentage processed
                                    // should be accurate enough so that if it is at 100%, then no more log entries are added.
                                    // We can only guarantee that when we have processed all lines and therefore we reserve
                                    // setting the percentage to 100% ONLY when we can read no more lines
                                    // (See the SetEndOfSourceReached() call below, outside the loop).
                                    UpdatePercentageProcessed(stream.Position, fileSize, allow100Percent: false);

                                    SynchronizePropertiesWithUser();
                                }
                            }

                            _lastStreamPosition = stream.Position;
                            _localProperties.SetValue(TextProperties.LineCount, _entries.Count);
                            _localProperties.SetValue(Core.Properties.LogEntryCount, _entries.Count);
                        }
                    }

                    Listeners.OnRead(_numberOfLinesRead);
                    SetEndOfSourceReached();
                }
            }
            catch (FileNotFoundException e)
            {
                SetError(_sourceDoesNotExist);
                Log.Debug(e);
            }
            catch (DirectoryNotFoundException e)
            {
                SetError(_sourceDoesNotExist);
                Log.Debug(e);
            }
            catch (OperationCanceledException e)
            {
                Log.Debug(e);
            }
            catch (UnauthorizedAccessException e)
            {
                SetError(_sourceCannotBeAccessed);
                Log.Debug(e);
            }
            catch (IOException e)
            {
                SetError(_sourceCannotBeAccessed);
                Log.Debug(e);
            }
            catch (Exception e)
            {
                Log.Debug(e);
            }

            if (read)
            {
                return(TimeSpan.Zero);
            }

            return(TimeSpan.FromMilliseconds(100));
        }