Пример #1
0
        public IExtractor ExtractFile(ulong index, string outputDirectory)
        {
            if (index >= (ulong)_Files.LongLength)
            {
                throw new ArgumentOutOfRangeException($"Index `{index}` is out of range.");
            }

            SevenZipArchiveFile file = _Files[index];

            if (!preProcessFile(outputDirectory, file))
            {
                string fullPath = Path.Combine(outputDirectory, PreserveDirectoryStructure ? file.Name : Path.GetFileName(file.Name));

                // progress provider
                SevenZipProgressProvider szpp = null;
                if (ProgressDelegate != null)
                {
                    szpp = new SevenZipProgressProvider(_Files, new[] { index }, ProgressDelegate);
                }

                // extraction
                //Trace.TraceInformation($"Filename: `{file.Name}`, file size: `{file.Size} bytes`.");
                var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo, Password);
                using (Stream fileStream = File.Create(fullPath))
                    sx.Extract((ulong)file.UnPackIndex, fileStream, szpp);
                if (file.Time != null)
                {
                    File.SetLastWriteTimeUtc(fullPath, (DateTime)file.Time);
                }
            }

            return(this);
        }
Пример #2
0
        public IExtractor ExtractFile(ulong index, Stream outputStream)
        {
            if (index >= (ulong)_Files.LongLength)
            {
                throw new ArgumentOutOfRangeException($"Index `{index}` is out of range.");
            }
            if (outputStream == null || !outputStream.CanWrite)
            {
                throw new ArgumentException($"Stream `{nameof(outputStream)}` is invalid or cannot be written to.");
            }

            SevenZipArchiveFile file = _Files[index];

            if (file.IsEmpty)
            {
                //Trace.TraceWarning($"Filename: {file.Name} is a directory, empty file or anti file, nothing to output to stream.");
            }
            else
            {
                // progress provider
                SevenZipProgressProvider szpp = null;
                if (ProgressDelegate != null)
                {
                    szpp = new SevenZipProgressProvider(_Files, new[] { index }, ProgressDelegate);
                }

                // extraction
                //Trace.TraceInformation($"Filename: `{file.Name}`, file size: `{file.Size} bytes`.");
                //Trace.TraceInformation("Extracting...");
                var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo, Password);
                sx.Extract((ulong)file.UnPackIndex, outputStream, szpp);
            }

            return(this);
        }
Пример #3
0
        public IExtractor ExtractFiles(ulong[] indices, Func <ArchiveFile, Stream> onStreamRequest, Action <ArchiveFile, Stream> onStreamClose = null)
        {
            if (indices.Any(index => index >= (ulong)_Files.LongLength))
            {
                throw new ArgumentOutOfRangeException("An index given in `indices[]` array is out of range.");
            }

            // preprocess files and keep track of streams to decompress
            var   streamToFileIndex = new Dictionary <ulong, ulong>();
            var   streamIndices     = new List <ulong>();
            ulong streamIndex       = 0;

            for (ulong i = 0; i < (ulong)_Files.LongLength; ++i)
            {
                if (!indices.Any() || Array.IndexOf(indices, i) != -1)
                {
                    if (_Files[i].IsEmpty)
                    {
                        using (Stream s = onStreamRequest(_Files[i]))
                            if (s != null)
                            {
                                onStreamClose?.Invoke(_Files[i], s);
                            }
                    }
                    else if (indices.Any())
                    {
                        streamIndices.Add(streamIndex);
                    }
                }
                if (!_Files[i].IsEmpty)
                {
                    streamToFileIndex[streamIndex++] = i;
                }
            }

            // no file to decompress
            if (!streamToFileIndex.Any())
            {
                //Trace.TraceWarning("ExtractFiles: No decoding required.");
                return(this);
            }

            // progress provider
            SevenZipProgressProvider szpp = null;

            if (ProgressDelegate != null)
            {
                szpp = new SevenZipProgressProvider(_Files, indices, ProgressDelegate);
            }

            // extraction
            //Trace.TraceInformation("Extracting...");
            var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo, Password);

            sx.ExtractMultiple(
                streamIndices.ToArray(),
                (ulong index) => onStreamRequest(_Files[streamToFileIndex[index]]),
                (ulong index, Stream stream) => onStreamClose?.Invoke(_Files[streamToFileIndex[index]], stream),
                szpp);

            return(this);
        }
Пример #4
0
        public IExtractor ExtractFiles(ulong[] indices, string outputDirectory)
        {
            if (indices.Any(index => index >= (ulong)_Files.LongLength))
            {
                throw new ArgumentOutOfRangeException("An index given in `indices[]` array is out of range.");
            }

            // preprocess files and keep track of streams to decompress
            var   streamToFileIndex = new Dictionary <ulong, ulong>();
            var   streamIndices     = new List <ulong>();
            ulong streamIndex       = 0;

            for (ulong i = 0; i < (ulong)_Files.LongLength; ++i)
            {
                if (!indices.Any() || Array.IndexOf(indices, i) != -1)
                {
                    if (!preProcessFile(outputDirectory, _Files[i]))
                    {
                        streamIndices.Add(streamIndex);
                    }
                }
                if (!_Files[i].IsEmpty)
                {
                    streamToFileIndex[streamIndex++] = i;
                }
            }

            // no file to decompress
            if (!streamIndices.Any())
            {
                //Trace.TraceWarning("ExtractFiles: No decoding required.");
                return(this);
            }

            // progress provider
            SevenZipProgressProvider szpp = null;

            if (ProgressDelegate != null)
            {
                szpp = new SevenZipProgressProvider(_Files, indices, ProgressDelegate);
            }

            // extraction
            //Trace.TraceInformation("Extracting...");
            var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo, Password);

            sx.ExtractMultiple(
                streamIndices.ToArray(),
                (ulong index) => {
                SevenZipArchiveFile file = _Files[streamToFileIndex[index]];
                string fullPath          = Path.Combine(outputDirectory, PreserveDirectoryStructure ? file.Name : Path.GetFileName(file.Name));

                //Trace.TraceInformation($"File index {index}, filename: {file.Name}, file size: {file.Size}");
                return(new FileStream(fullPath,
                                      FileMode.Create,
                                      FileAccess.Write,
                                      FileShare.None,
                                      bufferSize));
            },
                (ulong index, Stream stream) => {
                stream.Close();
                SevenZipArchiveFile file = _Files[streamToFileIndex[index]];
                string fullPath          = Path.Combine(outputDirectory, PreserveDirectoryStructure ? file.Name : Path.GetFileName(file.Name));
                if (file.Time != null)
                {
                    File.SetLastWriteTimeUtc(fullPath, (DateTime)file.Time);
                }
            },
                szpp);

            return(this);
        }