Comment on this RCR (edit wiki page) | RCRchive home

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



Vote for this RCR

Strongly opposed [0]
Opposed [3]
Neutral [0]
In favor [1]
Strongly advocate [0]

Change the status of this RCR to:

accepted

rejected

withdrawn


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