Class: Omnizip::Formats::SevenZip::SplitArchiveReader

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/seven_zip/split_archive_reader.rb

Overview

Split archive reader for .7z format Reads multi-volume archives

Defined Under Namespace

Classes: MultiVolumeIO

Constant Summary

Constants included from Constants

Constants::MAJOR_VERSION, Constants::MAX_NUM_BONDS, Constants::MAX_NUM_CODERS, Constants::MAX_NUM_PACK_STREAMS, Constants::MINOR_VERSION, Constants::SIGNATURE, Constants::SIGNATURE_SIZE, Constants::START_HEADER_SIZE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_path) ⇒ SplitArchiveReader

Initialize reader with base path

Parameters:

  • base_path (String)

    Path to first volume (e.g., "backup.7z.001")



18
19
20
21
22
23
24
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 18

def initialize(base_path)
  @base_path = base_path
  @entries = []
  @stream_info = nil
  @volumes = []
  @volume_handles = []
end

Instance Attribute Details

#base_pathObject (readonly)

Returns the value of attribute base_path.



13
14
15
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 13

def base_path
  @base_path
end

#entriesObject (readonly)

Returns the value of attribute entries.



13
14
15
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 13

def entries
  @entries
end

#headerObject (readonly)

Returns the value of attribute header.



13
14
15
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 13

def header
  @header
end

#stream_infoObject (readonly)

Returns the value of attribute stream_info.



13
14
15
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 13

def stream_info
  @stream_info
end

#volumesObject (readonly)

Returns the value of attribute volumes.



13
14
15
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 13

def volumes
  @volumes
end

Instance Method Details

#closeObject

Close all volume handles



118
119
120
121
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 118

def close
  @volume_handles.each(&:close)
  @volume_handles.clear
end

#extract_all(output_dir) ⇒ Object

Extract all files to directory

Parameters:

  • output_dir (String)

    Destination directory

Raises:

  • (RuntimeError)

    on extraction error



101
102
103
104
105
106
107
108
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 101

def extract_all(output_dir)
  FileUtils.mkdir_p(output_dir)

  @entries.each do |entry|
    output_path = File.join(output_dir, entry.name)
    extract_entry(entry.name, output_path)
  end
end

#extract_entry(entry_name, output_path) ⇒ Object

Extract file to output path

Parameters:

  • entry_name (String)

    File name to extract

  • output_path (String)

    Destination path

Raises:

  • (RuntimeError)

    if entry not found or extraction fails



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 71

def extract_entry(entry_name, output_path)
  entry = @entries.find { |e| e.name == entry_name }
  raise "Entry not found: #{entry_name}" unless entry

  # Create directory if needed
  FileUtils.mkdir_p(File.dirname(output_path))

  # Extract file
  if entry.directory?
    FileUtils.mkdir_p(output_path)
  elsif entry.has_stream?
    data = extract_entry_data(entry)
    File.binwrite(output_path, data)

    # Set timestamp if available
    if entry.mtime
      File.utime(entry.atime || entry.mtime || Time.now,
                 entry.mtime || Time.now,
                 output_path)
    end
  else
    # Empty file
    FileUtils.touch(output_path)
  end
end

#list_filesArray<Models::FileEntry>

List all files in archive

Returns:



62
63
64
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 62

def list_files
  @entries
end

#openObject

Detect and open all volumes

Raises:

  • (RuntimeError)

    if files cannot be opened or parsed



29
30
31
32
33
34
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 29

def open
  detect_volumes
  open_volumes
  parse_archive
  self
end

#split?Boolean

Check if archive is split

Returns:

  • (Boolean)

    true if split across multiple volumes



39
40
41
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 39

def split?
  @volumes.size > 1
end

#total_volumesInteger

Get total number of volumes

Returns:

  • (Integer)

    Number of volumes



46
47
48
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 46

def total_volumes
  @volumes.size
end

#valid?Boolean

Check if archive is valid .7z format

Returns:

  • (Boolean)

    true if valid



113
114
115
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 113

def valid?
  !@header.nil? && @header.valid?
end

#volume_sizeInteger

Get volume size (first volume)

Returns:

  • (Integer)

    Volume size in bytes



53
54
55
56
57
# File 'lib/omnizip/formats/seven_zip/split_archive_reader.rb', line 53

def volume_size
  return 0 if @volumes.empty?

  File.size(@volumes.first)
end