示例#1
0
        /// <summary>
        /// Получить части архивированного потока.
        /// </summary>
        /// <param name="sourceStream">Архивированный поток.</param>
        /// <returns>Список частей архива.</returns>
        private List <ArchivePart> GetArchiveParts(Stream sourceStream)
        {
            if (_archiveParts != null && _archiveParts.Any())
            {
                return(_archiveParts);
            }

            long offset = 0;
            var  portionSizeBufferLength = sizeof(long);
            var  portionSizeBuffer       = new byte[portionSizeBufferLength];

            var parts = new List <ArchivePart>();

            while (offset + portionSizeBufferLength < sourceStream.Length)
            {
                sourceStream.Seek(offset, SeekOrigin.Begin);
                sourceStream.Read(portionSizeBuffer, 0, portionSizeBufferLength);
                var portionBufferLength = BitConverter.ToInt32(portionSizeBuffer, 0);
                offset += portionSizeBufferLength;

                var archivePart = new ArchivePart(offset, portionBufferLength);
                parts.Add(archivePart);

                offset += portionBufferLength;
            }

            return(parts);
        }
示例#2
0
        /// <summary>
        /// Выполнить архивацию файла.
        /// </summary>
        /// <param name="sourceStream">Исходный поток.</param>
        /// <param name="targetStream">Архивированный поток.</param>
        /// <param name="bufferSize">Размер буфера.</param>
        private void CompressInternal(Stream sourceStream, Stream targetStream, long bufferSize)
        {
            var parts = Math.Ceiling((double)sourceStream.Length / bufferSize);

            if (bufferSize > sourceStream.Length)
            {
                bufferSize = sourceStream.Length;
            }

            for (var portion = 0; portion < parts; portion++)
            {
                var currentPortion = portion;
                var archivePart    = new ArchivePart();
                var size           = bufferSize;

                var offset = currentPortion * size;
                if (offset + size > sourceStream.Length)
                {
                    size = sourceStream.Length - offset;
                }

                archivePart.Offset = offset;
                var compressingTask = new ProcessingTask(() =>
                {
                    var portionArray = new byte[size];
                    lock (sourceStream)
                    {
                        sourceStream.Seek(archivePart.Offset, SeekOrigin.Begin);
                        sourceStream.Read(portionArray, 0, (int)size);
                    }

                    archivePart.Input = portionArray;
                    archivePart.Compress();
                });

                _queueManager.CompressQueue.Enqueue(compressingTask);

                var writingTask = new ProcessingTask(() =>
                {
                    while (true)
                    {
                        if (!archivePart.HasResult)
                        {
                            continue;
                        }

                        lock (targetStream)
                            archivePart.WriteResult(targetStream);
                        break;
                    }
                });

                _queueManager.WritingQueue.Enqueue(writingTask);
            }
        }