class Net::SFTP::Operations::File

A wrapper around an SFTP file handle, that exposes an IO-like interface for interacting with the remote file. All operations are synchronous (blocking), making this a very convenient way to deal with remote files.

A wrapper is usually created via the Net::SFTP::Session#file factory:

file = sftp.file.open("/path/to/remote")
puts file.gets
file.close

Attributes

handle[R]

The SFTP file handle object that this object wraps

pos[R]

The current position within the remote file

sftp[R]

A reference to the Net::SFTP::Session instance that drives this wrapper

Public Class Methods

new(sftp, handle) click to toggle source

Creates a new wrapper that encapsulates the given handle (such as would be returned by Net::SFTP::Session#open!). The sftp parameter must be the same Net::SFTP::Session instance that opened the file.

# File lib/net/sftp/operations/file.rb, line 27
def initialize(sftp, handle)
  @sftp     = sftp
  @handle   = handle
  @pos      = 0
  @real_pos = 0
  @real_eof = false
  @buffer   = ""
end

Public Instance Methods

close() click to toggle source

Closes the underlying file and sets the handle to nil. Subsequent operations on this object will fail.

# File lib/net/sftp/operations/file.rb, line 46
def close
  sftp.close!(handle)
  @handle = nil
end
eof?() click to toggle source

Returns true if the end of the file has been encountered by a previous read. Setting the current file position via pos= will reset this flag (useful if the file’s contents have changed since the EOF was encountered).

# File lib/net/sftp/operations/file.rb, line 55
def eof?
  @real_eof && @buffer.empty?
end
gets(sep_or_limit=$/, limit=Float::INFINITY) click to toggle source

Reads up to the next instance of sep_string in the stream, and returns the bytes read (including sep_string). If sep_string is omitted, it defaults to +$/+. If EOF is encountered before any data could be read, gets will return nil. If the first argument is an integer, or optional second argument is given, the returning string would not be longer than the given value in bytes.

# File lib/net/sftp/operations/file.rb, line 87
def gets(sep_or_limit=$/, limit=Float::INFINITY)
  if sep_or_limit.is_a? Integer
    sep_string = $/
    lim = sep_or_limit
  else
    sep_string = sep_or_limit
    lim = limit
  end

  delim = if sep_string && sep_string.length == 0
    "#{$/}#{$/}"
  else
    sep_string
  end

  loop do
    at = @buffer.index(delim) if delim
    if at
      offset = [at + delim.length, lim].min
      @pos += offset
      line, @buffer = @buffer[0,offset], @buffer[offset..-1]
      return line
    elsif lim < @buffer.length
      @pos += lim
      line, @buffer = @buffer[0,lim], @buffer[lim..-1]
      return line
    elsif !fill
      return nil if @buffer.empty?
      @pos += @buffer.length
      line, @buffer = @buffer, ""
      return line
    end
  end
end
pos=(offset) click to toggle source

Repositions the file pointer to the given offset (relative to the start of the file). This will also reset the EOF flag.

# File lib/net/sftp/operations/file.rb, line 38
def pos=(offset)
  @real_pos = @pos = offset
  @buffer = ""
  @real_eof = false
end
print(*items) click to toggle source

Writes each argument to the stream. If +$+ is set, it will be written after all arguments have been written.

puts(*items) click to toggle source

Writes each argument to the stream, appending a newline to any item that does not already end in a newline. Array arguments are flattened.

# File lib/net/sftp/operations/file.rb, line 159
def puts(*items)
  items.each do |item|
    if Array === item
      puts(*item)
    else
      write(item)
      write("\n") unless item[-1] == ?\n
    end
  end
  nil
end
read(n=nil) click to toggle source

Reads up to n bytes of data from the stream. Fewer bytes will be returned if EOF is encountered before the requested number of bytes could be read. Without an argument (or with a nil argument) all data to the end of the file will be read and returned.

This will advance the file pointer (pos).

# File lib/net/sftp/operations/file.rb, line 65
def read(n=nil)
  loop do
    break if n && @buffer.length >= n
    break unless fill
  end

  if n
    result, @buffer = @buffer[0,n], (@buffer[n..-1] || "")
  else
    result, @buffer = @buffer, ""
  end

  @pos += result.length
  return result
end
readline(sep_or_limit=$/, limit=Float::INFINITY) click to toggle source

Same as gets, but raises EOFError if EOF is encountered before any data could be read.

# File lib/net/sftp/operations/file.rb, line 124
def readline(sep_or_limit=$/, limit=Float::INFINITY)
  line = gets(sep_or_limit, limit)
  raise EOFError if line.nil?
  return line
end
rewind() click to toggle source

Resets position to beginning of file

# File lib/net/sftp/operations/file.rb, line 153
def rewind
  self.pos = 0
end
size() click to toggle source
# File lib/net/sftp/operations/file.rb, line 148
def size
  stat.size
end
stat() click to toggle source

Performs an fstat operation on the handle and returns the attribute object (Net::SFTP::Protocol::V01::Attributes, Net::SFTP::Protool::V04::Attributes, or Net::SFTP::Protocol::V06::Attributes, depending on the SFTP protocol version in use).

# File lib/net/sftp/operations/file.rb, line 175
def stat
  sftp.fstat!(handle)
end
write(data) click to toggle source

Writes the given data to the stream, incrementing the file position and returning the number of bytes written.

# File lib/net/sftp/operations/file.rb, line 132
def write(data)
  data = data.to_s
  sftp.write!(handle, @real_pos, data)
  @real_pos += data.bytes.length
  @pos = @real_pos
  data.bytes.length
end

Private Instance Methods

fill() click to toggle source

Fills the buffer. Returns true if it succeeded, and false if EOF was encountered before any data was read.

# File lib/net/sftp/operations/file.rb, line 183
def fill
  data = sftp.read!(handle, @real_pos, 8192)

  if data.nil?
    @real_eof = true
    return false
  else
    @real_pos += data.length
    @buffer << data
  end

  !@real_eof
end