Beispiel #1
0
        byte[] ReadBuffer = new byte[1024 * 128 * 1]; // кеш - 0.5 Мб
        void DownloadFileStreamly(Stream dataStream)
        {
            DownloadProgress CurrentDownloadProgress = new DownloadProgress();
            Stream           WriteStream             = null;
            Exception        TempEx = null;

            try
            {
                if (Current.DownloadPathSave != null)
                {
                    string FilePath = Current.DownloadPathSave + "\\" + Current.Filename;

                    if (System.IO.File.Exists(FilePath))
                    {
                        System.IO.FileInfo xx = new System.IO.FileInfo(FilePath);
                        if (xx.Length > Current.FileSize)
                        {
                            xx.Delete();
                            Current.BytesDownloaded = 0;
                        }
                    }
                    else
                    {
                        Current.BytesDownloaded = 0;
                    }
                    WriteStream = new FileStream(FilePath, FileMode.OpenOrCreate);
                    CurrentDownloadProgress.FilePath = FilePath;
                }
                else
                {
                    WriteStream = Current.OutputData;
                }

                if (Current.FileSize == Current.BytesDownloaded && Current.BytesDownloaded != 0 &&
                    Current.FileDownloaded)
                {
                    throw new Exception("Файл уже закачан " + Current.FullURL);
                }

                if (Current.FileSize > 0 && Current.BytesDownloaded == 0 &&
                    WriteStream.Length != Current.FileSize)
                {   // если известен размер файла и файл только что добавили, то создаем пустышку в размер файла
                    WriteStream.SetLength(Current.FileSize);
                }

                if (WriteStream.Length == Current.BytesDownloaded && WriteStream.Length != 0)
                {
                    Current.BytesDownloaded = 0;
                }

                WriteStream.Position = Current.BytesDownloaded;

                DateTime BeginTime = DateTime.Now;
                TimeSpan TimeDifference;
                TimeSpan RemainTime;

                int    BeginDownloadBytes        = Current.BytesDownloaded;
                int    ReadData                  = 1;
                int    BufferOffset              = 0;
                double LastTimeDifferenceSeconds = 0;

                while (DownloadFileThreadRunning)
                {
                    if (!DownloadFileThreadPause)
                    { // если не была задана пауза
                        ReadData      = dataStream.Read(ReadBuffer, BufferOffset, ReadBuffer.Length - BufferOffset);
                        BufferOffset += ReadData;

                        TimeDifference = DateTime.Now - BeginTime;

                        if (((ReadBuffer.Length - BufferOffset) < 1024) ||              // осталось черезчур мало места в буффере
                            (ReadData == 0) ||                                          // закачка закончилась
                            (TimeDifference.TotalSeconds != LastTimeDifferenceSeconds)) // но не реже 1 раза в секунду
                        {
                            WriteStream.Write(ReadBuffer, 0, BufferOffset);
                            Current.BytesDownloaded += BufferOffset;

                            if (TimeDifference.TotalSeconds != LastTimeDifferenceSeconds)
                            {
                                CurrentDownloadProgress.DownloadSize = Math.Max(Current.BytesDownloaded, Current.FileSize);
                                CurrentDownloadProgress.Bytes        = Current.BytesDownloaded;
                                CurrentDownloadProgress.Speed        = (
                                    (Current.BytesDownloaded - BeginDownloadBytes) * 1000.0f
                                    / (float)TimeDifference.TotalMilliseconds);

                                RemainTime = new TimeSpan((long)
                                                          ((TimeDifference.Ticks * (Current.FileSize - Current.BytesDownloaded))
                                                           / (float)(Current.BytesDownloaded - BeginDownloadBytes))
                                                          );

                                CurrentDownloadProgress.RemainTime = RemainTime.ToString();

                                CurrentDownloadProgress.Type = DownloadMessageType.DownloadProgressShow;
                                SygnalEventProgress(CurrentDownloadProgress);

                                if (TimeDifference.TotalSeconds >= 5)
                                {
                                    BeginTime          = DateTime.Now;
                                    BeginDownloadBytes = Current.BytesDownloaded;
                                }
                            }
                            ;

                            BufferOffset = 0;
                            LastTimeDifferenceSeconds = TimeDifference.TotalSeconds;
                        }
                    }
                    else
                    {// была задана пауза
                        CurrentDownloadProgress.Type = DownloadMessageType.DownloadPaused;
                        SygnalEventProgress(CurrentDownloadProgress);
                        Thread.Sleep(500);
                    }

                    if (ReadData == 0)
                    {     // все закачали
                        if (Current.FileSize == -1)
                        { // не был известен размер файла
                            Current.FileSize = Current.BytesDownloaded;
                        }
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                TempEx = ex;
                //    ErrorWork(new Exception("Размер файла " + Current.FileSize));
            }
            finally
            {
                WriteStream.Close();

                // финальное состояние
                CurrentDownloadProgress.DownloadSize = Math.Max(Current.BytesDownloaded, Current.FileSize);
                CurrentDownloadProgress.Bytes        = Current.BytesDownloaded;
                CurrentDownloadProgress.Type         = DownloadMessageType.DownloadProgressShow;
                SygnalEventProgress(CurrentDownloadProgress);

                if (DownloadFileThreadRunning && Current.FileSize == Current.BytesDownloaded)
                {   // файл закончен
                    CurrentDownloadProgress.Type = DownloadMessageType.DownloadFinished;
                    SygnalEventProgress(CurrentDownloadProgress);
                    Current.FileDownloaded = true;
                }
                else
                { // была нажата кнопка стоп -поэтому - ничего не вызываем
                    CurrentDownloadProgress.Type           = DownloadMessageType.DownloadStopped;
                    CurrentDownloadProgress.AdditionalInfo = "DownloadFileThreadRunning " + DownloadFileThreadRunning.ToString() +
                                                             " Current.FileSize = " + Current.FileSize.ToString() +
                                                             " Current.BytesDownloaded = " + Current.BytesDownloaded.ToString();
                    SygnalEventProgress(CurrentDownloadProgress);
                }

                DownloadFileThreadRunning = false;
            }
            if (TempEx != null)
            {
                throw TempEx;
            }
        }