RCR 212: cat fileutil.
submitted by cyent on Wed Feb 11 2004 06:59:46 PM -0800
Status: withdrawn
Abstract
Add class method cat to file utils to mimic in a portable fashion the unix `cat` program,
Problem
Often I do.... string = File.open('filename') {|i| i.sysread(i.stat.size)} To get a smallish file into a string. I could also do... file = `cat filename` Which is actually quite cute. That allows me to do... string = `cat filename.1 filename.2 filename.3` But there are a couple of things I don't like about that. 1) It's non-portable, (it assumes the existence of a 'cat' program) 2) It actually invokes bash to do the PATH look up and globbing. I would like to add 'cat' to fileutils.rb so I can do... string = FileUtils.cat( 'filename.1', 'filename.2')
Proposal
Add to fileutils.rb T... 'filename.1 def cat(*name) result = '' name.each {|n| File.open('filename') {|i| result += i.sysread(i.stat.size)}} result end
Analysis
This implementation fails if filename refers to a named pipe. It should be extended to detect named pipes and iteratively suck on them until dry (hit eof). Possibly it should detect if a block is passed so you can do... FileUtils.cat( 'file.1', 'file.2') do |line| do stuff with line end Should also handle names pipes correctly.
Implementation
#!/usr/local/bin/ruby -w module FileUtils # # Like the unix 'cat' programs, reads all the files named # and concatenates them into one long string. # def cat(*file_names) if block_given? puts "block" file_names.each do |file_name| File.open( file_name) do |inf| inf.each do |line| yield line end end end else result = '' file_names.each do |file_name| File.open( file_name) do |inf| if inf.stat.file? result += inf.sysread( inf.stat.size) else begin result += inf.sysread( 65536) while true rescue EOFError end end end end return result end end end # # eof - now for unit tests # if $0 == __FILE__ require 'test/unit' include FileUtils class TC_FileCat < Test::Unit::TestCase def test_cat assert_equal( '', FileUtils::cat()) assert( FileUtils::cat( $0) =~ %r{ module\ FileUtils }x) end end # class TC_FileCat end # if $0 == __FILE__
Do you really need concatenation? If you want to read whole single file,
File.read(path)
is much simpler.
-- matz.
Add comments here
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog