Ejemplo n.º 1
0
        public IExtractor ExtractFile(UInt64 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
            {
                Trace.TraceInformation($"Filename: `{file.Name}`, file size: `{file.Size} bytes`.");

                var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo);
                sx.Extract((UInt64)file.UnPackIndex, outputStream);
            }

            return(this);
        }
Ejemplo n.º 2
0
        public IExtractor ExtractFile(UInt64 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((UInt64)file.UnPackIndex, fileStream, szpp);
                if (file.Time != null)
                {
                    File.SetLastWriteTimeUtc(fullPath, (DateTime)file.Time);
                }
            }

            return(this);
        }
Ejemplo n.º 3
0
        public IExtractor ExtractFiles(UInt64[] 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.");
            }

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

            var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo);

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

            return(this);
        }
Ejemplo n.º 4
0
        public IExtractor ExtractFile(UInt64 index, string outputDirectory)
        {
            if (index >= (ulong)_Files.LongLength)
            {
                throw new ArgumentOutOfRangeException($"Index `{index}` is out of range.");
            }

            SevenZipArchiveFile file = _Files[index];

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            if (!processFile(outputDirectory, file))
            {
                string fullPath = Path.Combine(outputDirectory, PreserveDirectoryStructure ? file.Name : Path.GetFileName(file.Name));
                if (File.Exists(fullPath) && !OverwriteExistingFiles && !SkipExistingFiles)
                {
                    throw new IOException($"File `{file.Name}` already exists.");
                }
                if (!File.Exists(fullPath) || OverwriteExistingFiles)
                {
                    Trace.TraceInformation($"Filename: `{file.Name}`, file size: `{file.Size} bytes`.");

                    var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo);
                    using (Stream fileStream = File.Create(fullPath))
                        sx.Extract((UInt64)file.UnPackIndex, fileStream);
                    if (file.Time != null)
                    {
                        File.SetLastWriteTimeUtc(fullPath, (DateTime)file.Time);
                    }
                }
                else
                {
                    Trace.TraceWarning($"File `{file.Name} already exists, skipping.");
                }
            }

            return(this);
        }
Ejemplo n.º 5
0
        public IExtractor ExtractFiles(UInt64[] indices, string outputDirectory)
        {
            if (indices.Any(index => index >= (ulong)_Files.LongLength))
            {
                throw new ArgumentOutOfRangeException("An index given in `indices[]` array is out of range.");
            }

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            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 (!processFile(outputDirectory, _Files[i]))
                    {
                        if (indices.Any())
                        {
                            streamIndices.Add(streamIndex);
                        }
                    }
                }
                if (!_Files[i].IsEmpty)
                {
                    streamToFileIndex[streamIndex++] = i;
                }
            }

            var sx = new SevenZipStreamsExtractor(stream, header.RawHeader.MainStreamsInfo);

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

                if (File.Exists(fullPath) && !OverwriteExistingFiles && !SkipExistingFiles)
                {
                    throw new IOException($"File `{file.Name}` already exists.");
                }
                if (!File.Exists(fullPath) || OverwriteExistingFiles)
                {
                    return(new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None, 128 * 1024));
                }

                Trace.TraceWarning($"File `{file.Name} already exists, skipping.");
                return(null);
            },

                (ulong index, Stream stream) => {
                stream.Close();
                SevenZipArchiveFile file = _Files[streamToFileIndex[index]];
                string fullPath          = Path.Combine(outputDirectory, file.Name);
                if (file.Time != null)
                {
                    File.SetLastWriteTimeUtc(fullPath, (DateTime)file.Time);
                }
            });

            return(this);
        }
Ejemplo n.º 6
0
        public IExtractor ExtractFiles(UInt64[] 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);
        }
Ejemplo n.º 7
0
        public IExtractor ExtractFiles(UInt64[] 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);
        }