예제 #1
0
        /// <summary>
        /// </summary>
        /// <param name="Algo"></param>
        public byte[] ComputeLargeStreamHash(Stream Stream, RateTracker Tracker, ChecksumProgressEventHandler Callback)
        {
            // Buffer size optimized for reading massive files.
            byte[] buffer = MemoryPool.AllocBuffer(BufferSize);
            int    bytesRead;

            do
            {
                bytesRead = Stream.Read(buffer, 0, BufferSize);
                if (bytesRead > 0)
                {
                    HashCore(buffer, 0, bytesRead);

                    if (Callback != null)
                    {
                        Callback?.Invoke(bytesRead);
                    }

                    if (Tracker != null)
                    {
                        Tracker.Out(bytesRead);
                    }
                }
            } while (bytesRead > 0);

            HashValue = HashFinal();
            byte[] Tmp = (byte[])HashValue.Clone();
            Initialize();

            MemoryPool.ReleaseBuffer(buffer);
            return(Tmp);
        }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <param name="Stm"></param>
        /// <param name="Work"></param>
        /// <param name="Offset"></param>
        /// <param name="Size"></param>
        private void ReadWithOffset(ActiveStream Stm, Task Work, int Offset)
        {
            lock (Stm)
            {
                try
                {
                    Stm.Stream.Seek(Work.Offset + Offset, SeekOrigin.Begin);
                    Stm.Stream.BeginRead(
                        Work.Data, (int)Work.DataOffset + Offset, (int)Work.Size - Offset, Result =>
                    {
                        try
                        {
                            int BytesRead = Stm.Stream.EndRead(Result);
                            if (BytesRead == 0)
                            {
                                Logger.Log(LogLevel.Error, LogCategory.IO, "Failed to read file {0} at offset {1} size {2}. Encountered end of file.", Stm.Path, Work.Offset + Offset, Work.Size - Offset);
                                Work.Callback?.Invoke(false);
                            }
                            else
                            {
                                GlobalBandwidthStats.Out(BytesRead);

                                if (BytesRead < Work.Size)
                                {
                                    ReadWithOffset(Stm, Work, Offset + BytesRead);
                                    return;
                                }

                                ulong ElapsedTime = TimeUtils.Ticks - Work.QueueTime;
                                OutLatency.Add(ElapsedTime);

                                Work.Callback?.Invoke(true);
                            }
                        }
                        catch (Exception Ex)
                        {
                            Logger.Log(LogLevel.Error, LogCategory.IO, "Failed to read file {0} with error: {1}", Stm.Path, Ex.Message);

                            Work.Callback?.Invoke(false);
                        }
                        finally
                        {
                            Interlocked.Add(ref GlobalQueuedOut, -Work.Size);
                            Interlocked.Decrement(ref Stm.ActiveOperations);

                            WakeThread();
                        }
                    }, null
                        );
                }
                catch (Exception Ex)
                {
                    Logger.Log(LogLevel.Error, LogCategory.IO, "Failed to read to file {0} with error: {1}", Stm.Path, Ex.Message);

                    Work.Callback?.Invoke(false);
                    Interlocked.Add(ref GlobalQueuedOut, -Work.Size);
                    Interlocked.Decrement(ref Stm.ActiveOperations);

                    WakeThread();
                }
            }
        }