Beispiel #1
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);
        }
Beispiel #2
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);
        }