示例#1
0
        public void InputStreamOwnership()
        {
            var memStream = new TrackedMemoryStream();
            var s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

#if NET451
            s.Close();
#elif NETCOREAPP1_0
            s.Dispose();
#endif

            Assert.IsTrue(memStream.IsClosed, "Should be closed after parent owner close");
            Assert.IsTrue(memStream.IsDisposed, "Should be disposed after parent owner close");

            memStream = new TrackedMemoryStream();
            s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

            s.IsStreamOwner = false;
#if NET451
            s.Close();
#elif NETCOREAPP1_0
            s.Dispose();
#endif

            Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close");
            Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close");
        }
示例#2
0
        public static void ExtractArchive(string archivePath, string destinationDirectory, CancellationTokenEx cancellationToken,
                                          ReportCompressionStatus reportCompressionStatus, AddProcessingEntry addProcessingEntry)
        {
            bool   isTar;
            Stream inputStream = new FileStream(archivePath, FileMode.Open, FileAccess.Read);

            switch (Path.GetExtension(archivePath).ToUpper())
            {
            case ".ZIP":
                var fastZip = new FastZip();
                fastZip.ExtractZip(inputStream, destinationDirectory, FastZip.Overwrite.Always, null, null, null,
                                   true, true);
                //TODO: Add progress
                return;

            case ".TAR":
                isTar = true;
                break;

            case ".GZ":
                inputStream = new GZipInputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.gz", StringComparison.OrdinalIgnoreCase);
                break;

            case ".BZ2":
                inputStream = new BZip2InputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.bz2", StringComparison.OrdinalIgnoreCase);
                break;

            case ".LZW":
                inputStream = new LzwInputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.lzw", StringComparison.OrdinalIgnoreCase);
                break;

            default:
                inputStream.Dispose();
                return;
            }

            Directory.CreateDirectory(destinationDirectory);

            using (inputStream)
            {
                if (isTar)
                {
                    using (TarArchive tarArchive = TarArchive.CreateInputTarArchive(inputStream))
                    {
                        TarEntry        lastEntry           = null;
                        ProcessingEntry lastProcessingEntry = null;

                        tarArchive.ProgressMessageEvent += (archive, entry, message) =>
                        {
                            if (lastEntry != entry)
                            {
                                if (lastEntry != null)
                                {
                                    lastProcessingEntry.Progress = 1;
                                    lastProcessingEntry.Size     = entry.Size;
                                    ThreadPool.QueueUserWorkItem(state => reportCompressionStatus(lastProcessingEntry));
                                }

                                lastEntry           = entry;
                                lastProcessingEntry = new ProcessingEntry
                                {
                                    Action       = ProcessingEntryAction.Extracting,
                                    CreationTime = DateTime.UtcNow,
                                    Path         = entry.File,
                                    Progress     = 0,
                                    Name         = entry.Name
                                };
                                ThreadPool.QueueUserWorkItem(state => addProcessingEntry(lastProcessingEntry));
                            }
                        };
                        tarArchive.ExtractContents(destinationDirectory);
                    }
                }
                else
                {
                    var filename            = Path.GetFileNameWithoutExtension(archivePath);
                    var destinationFilePath = Path.Combine(destinationDirectory, filename);

                    var processingEntry = new ProcessingEntry
                    {
                        Action        = ProcessingEntryAction.Extracting,
                        CreationTime  = DateTime.UtcNow,
                        IsDirectory   = false,
                        IsInterminate = false,
                        LastAccess    = DateTime.UtcNow,
                        Path          = destinationFilePath,
                        Name          = filename
                    };

                    byte[] dataBuffer = new byte[4096];
                    using (var destinationFileStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        addProcessingEntry(processingEntry);

                        StreamUtils.Copy(inputStream, destinationFileStream, dataBuffer, (sender, args) =>
                        {
                            processingEntry.Progress = args.PercentComplete / 100;
                            processingEntry.Size     = destinationFileStream.Length;
                            args.ContinueRunning     = !cancellationToken.IsCanceled;
                            ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                        },
                                         TimeSpan.FromSeconds(1), null, null);

                        if (cancellationToken.IsCanceled)
                        {
                            processingEntry.Progress = -1;
                            ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                            return;
                        }

                        processingEntry.Progress = 1;
                        processingEntry.Size     = destinationFileStream.Length;
                        ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                    }
                }
            }
        }