preliminary support for F_GETPIPE_SZ and F_SETPIPE_SZ
[ruby_io_splice.git] / examples / splice-cp.rb
blobe629c5989f2df8de4a6d61d476fde0552fd01b6c
1 #!/usr/bin/env ruby
2 # -*- encoding: binary -*-
4 # Example of using IO.splice to copy a file
5 # This can be significantly faster than IO.copy_stream as data
6 # is never copied into userspace.
8 require 'io/splice'
10 usage = "#$0 SOURCE DEST"
11 source = ARGV.shift or abort usage
12 dest = ARGV.shift or abort usage
14 source = File.open(source, 'rb')
15 dest = File.open(dest, 'wb')
17 # We use a pipe as a ring buffer in kernel space.
18 # pipes may store up to IO::Splice::PIPE_CAPA bytes
19 rio, wio = pipe = IO.pipe
21 begin
22   nread = begin
23     # first pull as many bytes as possible into the pipe
24     IO.splice(source, nil, wio, nil, IO::Splice::PIPE_CAPA, 0)
25   rescue EOFError
26     break
27   end
29   # now move the contents of the pipe buffer into the destination file
30   # the copied data never enters userspace
31   nwritten = IO.splice(rio, nil, dest, nil, nread, 0)
33   nwritten == nread or
34     abort "short splice to destination file: #{nwritten} != #{nread}"
35 end while true