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; } }