Module: Zip::FileSplit

Included in:
File
Defined in:
lib/zip/file_split.rb

Overview

:nodoc:

Constant Summary collapse

MAX_SEGMENT_SIZE =
3_221_225_472
MIN_SEGMENT_SIZE =
65_536
DATA_BUFFER_SIZE =
8192

Instance Method Summary collapse

Instance Method Details

#get_partial_zip_file_name(zip_file_name, partial_zip_file_name) ⇒ Object



19
20
21
22
23
24
25
26
27
28
# File 'lib/zip/file_split.rb', line 19

def get_partial_zip_file_name(zip_file_name, partial_zip_file_name)
  unless partial_zip_file_name.nil?
    partial_zip_file_name = zip_file_name.sub(
      /#{::File.basename(zip_file_name)}\z/,
      partial_zip_file_name + ::File.extname(zip_file_name)
    )
  end
  partial_zip_file_name ||= zip_file_name
  partial_zip_file_name
end

#get_segment_count_for_split(zip_file_size, segment_size) ⇒ Object



30
31
32
33
# File 'lib/zip/file_split.rb', line 30

def get_segment_count_for_split(zip_file_size, segment_size)
  (zip_file_size / segment_size).to_i +
    ((zip_file_size % segment_size).zero? ? 0 : 1)
end

#get_segment_size_for_split(segment_size) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/zip/file_split.rb', line 9

def get_segment_size_for_split(segment_size)
  if MIN_SEGMENT_SIZE > segment_size
    MIN_SEGMENT_SIZE
  elsif MAX_SEGMENT_SIZE < segment_size
    MAX_SEGMENT_SIZE
  else
    segment_size
  end
end

#put_split_signature(szip_file, segment_size) ⇒ Object



35
36
37
38
39
# File 'lib/zip/file_split.rb', line 35

def put_split_signature(szip_file, segment_size)
  signature_packed = [SPLIT_FILE_SIGNATURE].pack('V')
  szip_file << signature_packed
  segment_size - signature_packed.size
end

#save_splited_part(zip_file, partial_zip_file_name, zip_file_size, szip_file_index, segment_size, segment_count) ⇒ Object

TODO: Make the code more understandable



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/zip/file_split.rb', line 44

def save_splited_part(
  zip_file, partial_zip_file_name, zip_file_size,
  szip_file_index, segment_size, segment_count
)
  ssegment_size  = zip_file_size - zip_file.pos
  ssegment_size  = segment_size if ssegment_size > segment_size
  szip_file_name = "#{partial_zip_file_name}.#{format('%03d', szip_file_index)}"
  ::File.open(szip_file_name, 'wb') do |szip_file|
    if szip_file_index == 1
      ssegment_size = put_split_signature(szip_file, segment_size)
    end
    chunk_bytes = 0
    until ssegment_size == chunk_bytes || zip_file.eof?
      segment_bytes_left = ssegment_size - chunk_bytes
      buffer_size        = [segment_bytes_left, DATA_BUFFER_SIZE].min
      chunk              = zip_file.read(buffer_size)
      chunk_bytes += buffer_size
      szip_file << chunk
      # Info for track splitting
      yield segment_count, szip_file_index, chunk_bytes, ssegment_size if block_given?
    end
  end
end

#split(zip_file_name, segment_size: MAX_SEGMENT_SIZE, delete_original: true, partial_zip_file_name: nil) ⇒ Object

Splits an archive into parts with segment size

Raises:



69
70
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/zip/file_split.rb', line 69

def split(
  zip_file_name, segment_size: MAX_SEGMENT_SIZE,
  delete_original: true, partial_zip_file_name: nil
)
  raise Error, "File #{zip_file_name} not found" unless ::File.exist?(zip_file_name)
  raise Errno::ENOENT, zip_file_name unless ::File.readable?(zip_file_name)

  zip_file_size = ::File.size(zip_file_name)
  segment_size  = get_segment_size_for_split(segment_size)
  return if zip_file_size <= segment_size

  segment_count = get_segment_count_for_split(zip_file_size, segment_size)
  ::Zip::File.open(zip_file_name) {} # Check for correct zip structure.
  partial_zip_file_name = get_partial_zip_file_name(zip_file_name, partial_zip_file_name)
  szip_file_index       = 0
  ::File.open(zip_file_name, 'rb') do |zip_file|
    until zip_file.eof?
      szip_file_index += 1
      save_splited_part(
        zip_file, partial_zip_file_name, zip_file_size,
        szip_file_index, segment_size, segment_count
      )
    end
  end
  ::File.delete(zip_file_name) if delete_original
  szip_file_index
end