Class: Omnizip::Chunked::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/chunked/writer.rb

Overview

Write large files incrementally in chunks

Constant Summary collapse

DEFAULT_CHUNK_SIZE =

64MB

64 * 1024 * 1024
FLUSH_THRESHOLD =

Flush every N chunks

10

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output_path, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ Writer

Initialize a chunked writer

Parameters:

  • output_path (String)

    Path to output file

  • options (Hash)

    Writer options



16
17
18
19
20
21
22
# File 'lib/omnizip/chunked/writer.rb', line 16

def initialize(output_path, chunk_size: DEFAULT_CHUNK_SIZE)
  @output_path = output_path
  @chunk_size = chunk_size
  @written = 0
  @chunks_written = 0
  @file_handle = nil
end

Instance Attribute Details

#chunk_sizeObject (readonly)

Returns the value of attribute chunk_size.



10
11
12
# File 'lib/omnizip/chunked/writer.rb', line 10

def chunk_size
  @chunk_size
end

#output_pathObject (readonly)

Returns the value of attribute output_path.



10
11
12
# File 'lib/omnizip/chunked/writer.rb', line 10

def output_path
  @output_path
end

#writtenObject (readonly)

Returns the value of attribute written.



10
11
12
# File 'lib/omnizip/chunked/writer.rb', line 10

def written
  @written
end

Class Method Details

.with_writer(output_path, **options) {|writer| ... } ⇒ Integer

Execute block with writer, auto-close

Yields:

  • (writer)

    Block to write data

Returns:

  • (Integer)

    Total bytes written



96
97
98
99
100
101
102
103
104
# File 'lib/omnizip/chunked/writer.rb', line 96

def self.with_writer(output_path, **options)
  writer = new(output_path, **options)
  begin
    yield writer
    writer.written
  ensure
    writer.close
  end
end

Instance Method Details

#closeself

Close the file handle

Returns:

  • (self)


78
79
80
81
82
83
84
85
# File 'lib/omnizip/chunked/writer.rb', line 78

def close
  if @file_handle
    flush
    @file_handle.close
    @file_handle = nil
  end
  self
end

#finishself

Finalize the file (alias for close)

Returns:

  • (self)


89
90
91
# File 'lib/omnizip/chunked/writer.rb', line 89

def finish
  close
end

#flushself

Flush buffered data to disk

Returns:

  • (self)


71
72
73
74
# File 'lib/omnizip/chunked/writer.rb', line 71

def flush
  @file_handle&.flush
  self
end

#write_chunk(chunk) ⇒ Integer

Write a chunk to file

Parameters:

  • chunk (String)

    Data to write

Returns:

  • (Integer)

    Bytes written



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/omnizip/chunked/writer.rb', line 27

def write_chunk(chunk)
  ensure_file_open

  bytes = @file_handle.write(chunk)
  @written += bytes
  @chunks_written += 1

  # Flush periodically to disk
  flush if (@chunks_written % FLUSH_THRESHOLD).zero?

  bytes
end

#write_from(source) ⇒ Integer

Write data from a source in chunks

Parameters:

  • source (String, IO)

    Source to read from

Returns:

  • (Integer)

    Total bytes written



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

def write_from(source)
  case source
  when String
    # File path
    if File.exist?(source)
      Reader.new(source, chunk_size: @chunk_size).each_chunk do |chunk|
        write_chunk(chunk)
      end
    else
      # Treat as data
      write_chunk(source)
    end
  when IO, StringIO
    # IO object
    while (chunk = source.read(@chunk_size))
      break if chunk.empty?

      write_chunk(chunk)
    end
  else
    raise ArgumentError, "Unsupported source type: #{source.class}"
  end

  @written
end