Append to a file.
CREDIT: George Moschovitis
# File lib/core/facets/file/append.rb, line 7 def self.append(file, str) File.open(file, 'ab') { |f| f << str } end
Creates a new file, or overwrites an existing file, and writes a string into it. Can also take a block just like File#open, which is yielded after the string is writ.
str = 'The content for the file' File.create('myfile.txt', str)
CREDIT: George Moschovitis
# File lib/core/facets/file/create.rb, line 13 def self.create(path, str='', &blk) open(path, 'wb') do |f| f << str blk.call(f) if blk end end
Takes a file name string and returns or changes its extension.
Without a new extension argument, returns the extension of the file name. In this respect ext is like extname, but unlike extname it does not include the dot prefix.
With a new extension argument, changes the exension of the file name to the new extension and returns it.
Examples
File.ext('file.rb') # => 'rb' File.ext('file.rb', 'txt') # => 'file.txt' File.ext('file.rb', '.txt') # => 'file.txt' File.ext('file.rb', '') # => 'file'
This method can be used with String#file for more object-oriented notation:
'file.rb'.file.ext('txt') # => 'file.txt'
CREDIT: Lavir the Whiolet
# File lib/core/facets/file/ext.rb, line 25 def self.ext(filename, new_ext=nil) old_ext = extname(filename) if new_ext == nil old_ext.sub(/^\./, '') else new_ext = '.' + new_ext unless (new_ext.empty? || new_ext[0,1] == '.') filename.chomp(old_ext) + new_ext end end
Platform dependent null device.
CREDIT: Daniel Burger
# File lib/core/facets/file/null.rb, line 7 def self.null case RUBY_PLATFORM when /mswin/ 'NUL' when /amiga/ 'NIL:' when /openvms/ 'NL:' else '/dev/null' end end
Read in a file as binary data.
Assuming we had a binary file ‘binary.dat’.
File.read_binary('binary.dat')
CREDIT: George Moschovitis
# File lib/core/facets/file/read_binary.rb, line 11 def self.read_binary(fname) open(fname, 'rb') do |f| return f.read end end
Reads in a file, removes blank lines and removes lines starting with ‘#’ and then returns an array of all the remaining lines.
Thr remark indicator can be overridden via the :omit:
option,
which can be a regualar expression or a string that is match against the
start of a line.
CREDIT: Trans
# File lib/core/facets/file/read_list.rb, line 12 def self.read_list(filepath, options={}) chomp = options[:chomp] omit = case options[:omit] when Regexp omit when nil /^\s*\#/ else /^\s*#{Regexp.escape(omit)}/ end list = [] readlines(filepath).each do |line| line = line.strip.chomp(chomp) next if line.empty? next if omit === line list << line end list end
Opens a file as a string and writes back the string to the file at the end of the block.
Returns the number of written bytes or nil
if the file
wasn’t modified.
Note that the file will even be written back in case the block raises an exception.
Mode can either be “b” or “+” and specifies to open the file in binary mode (no mapping of the plattform’s newlines to “n” is done) or to append to it.
Assuming we had a file ‘message.txt’ and had a binary file ‘binary.dat’.
# Reverse contents of "message.txt" File.rewrite("message.txt") { |str| str.reverse } # Replace "foo" by "bar" in "binary.dat". File.rewrite("binary.dat", "b") { |str| str.gsub("foo", "bar") }
IMPORTANT: The old version of this method required in place modification of the file string. The new version will write whatever the block returns instead!!!
CREDIT: George Moschovitis
# File lib/core/facets/file/rewrite.rb, line 30 def self.rewrite(name, mode = "") #:yield: unless block_given? raise(ArgumentError, "Need to supply block to File.rewrite") end if mode.is_a?(Numeric) then flag, mode = mode, "" mode += "b" if flag & File::Constants::BINARY != 0 mode += "+" if flag & File::Constants::APPEND != 0 else mode.delete!("^b+") end old_str = open(name, "r#{mode}") { |file| file.read } #rescue "" old_str = old_str.clone begin new_str = yield(old_str) ensure if old_str != new_str open(name, "w#{mode}") { |file| file.write(new_str) } end end end
In place version of rewrite. This version of method requires that the string be modified in place within the block.
# Reverse contents of "message" File.rewrite("message.txt") { |str| str.reverse! } # Replace "foo" by "bar" in "binary" File.rewrite("binary.dat", "b") { |str| str.gsub!("foo", "bar") }
# File lib/core/facets/file/rewrite.rb, line 64 def self.rewrite!(name, mode = "") #:yield: unless block_given? raise(ArgumentError, "Need to supply block to File.rewrite") end if mode.is_a?(Numeric) then flag, mode = mode, "" mode += "b" if flag & File::Constants::BINARY != 0 mode += "+" if flag & File::Constants::APPEND != 0 else mode.delete!("^b+") end old_str = open(name, "r#{mode}") { |file| file.read } #rescue "" new_str = old_str.clone begin yield(new_str) ensure if old_str != new_str open(name, "w#{mode}") { |file| file.write(new_str) } end end end
Returns only the first portion of the directory of a file path name.
File.rootname('lib/jump.rb') #=> 'lib' File.rootname('/jump.rb') #=> '/' File.rootname('jump.rb') #=> '.'
CREDIT: Trans
# File lib/core/facets/file/rootname.rb, line 12 def self.rootname(path) # -- this should be fairly robust path_re = Regexp.new('[' + Regexp.escape(File::Separator + %q{\/}) + ']') head, tail = path.split(path_re, 2) return '.' if path == head return '/' if head.empty? return head end
Cleans up a filename to ensure it will work on a filesystem.
File.sanitize("yo+baby!") #=> 'yo+baby_' File.sanitize(".what&up") #=> '.what_up'
CREDIT: George Moschovitis
# File lib/core/facets/file/sanitize.rb, line 10 def self.sanitize(filename) filename = File.basename(filename.gsub("\\", "/")) # work-around for IE filename.gsub!(/[^a-zA-Z0-9\.\-\+_]/,"_") filename = "_#{filename}" if filename =~ /^\.+$/ filename end
Splits a file path into an array of individual path components. This
differs from File.split
, which divides the path into only two
parts, directory path and basename.
File.split_all("a/b/c") #=> ['a', 'b', 'c']
CREDIT: Trans
# File lib/core/facets/file/split_all.rb, line 11 def self.split_all(path) head, tail = File.split(path) return [tail] if head == '.' || tail == '/' return [head, tail] if head == '/' return split_all(head) + [tail] end
Return the head of path from the rest of the path.
File.split_root('etc/xdg/gtk') #=> ['etc', 'xdg/gtk']
# File lib/core/facets/file/split_root.rb, line 7 def self.split_root(path) path_re = Regexp.new('[' + Regexp.escape(File::Separator + %q{\/}) + ']') path.split(path_re, 2) end
Writes the given data to the given path and closes the file. This is done
in binary mode, complementing IO.read
in standard Ruby.
str = 'The content for the file' File.write('write.txt', str)
Returns the number of bytes written.
CREDIT: Gavin Sinclair
# File lib/core/facets/file/write.rb, line 15 def self.write(path, data) File.open(path, "wb") do |file| return file.write(data) end end
Writes the given array of data to the given path and closes the file. This
is done in binary mode, complementing IO.readlines
in standard
Ruby.
Note that readlines
(the standard Ruby method) returns an
array of lines with newlines intact, whereas
writelines
uses puts
, and so appends newlines if
necessary. In this small way, readlines
and
writelines
are not exact opposites.
data = ['The content', ['for the file']] File.writelines('writelines.txt', data)
Returns number of lines written.
CREDIT: Noah Gibbs, Gavin Sinclair
# File lib/core/facets/file/writelines.rb, line 19 def self.writelines(path, data) File.open(path, "wb") do |file| file.puts(data) end data.size end
::yaml? provides a way to check if a file is a YAML formatted file:
File.yaml?('project.yaml') #=> true File.yaml?('project.xml') #=> false
Note this isn’t perfect. At present it depends on the use use of an initial document separator (eg. ‘—’). With YAML 1.1 the %YAML delaration is supposed to be manditory, so in the future this can be adapted to fit that standard.
# File lib/standard/facets/yaml.rb, line 39 def self.yaml?(file) File.open(file) do |f| until f.eof? line = f.gets break true if line =~ /^---/ break false unless line =~ /^(\s*#.*?|\s*)$/ end end end