From: Lloyd Zusman Date: 2002-08-11T11:41:00+09:00 Subject: Re: Something that corresponds to Perl's -T and -B tests? Lloyd Zusman writes: > ts writes: > >>>>>>> "L" == Lloyd Zusman writes: >> >> L> I've searched the Ruby documentation, and I can't find descriptions of >> L> anything that corresponds to Perl's `-T' and `-B' tests ... these test >> L> whether a file contains ASCII text or "binary" data, respectively. >> >> See [ruby-talk:44936] > > [ ... ] > > I'll wait a day or so to see if someone reports any other currently > written code, but if not, I'll write and post my own version here. I've written an extension to File::Stat which adds a textfile? and binaryfile? method. Each works pretty much the same as the file? and directory? methods of File::Stat. For example: s0 = File.stat("/etc/fstab") s1 = File.stat("/bin/sh") s2 = File.stat("/tmp") p s0.textfile? => true p s0.binaryfile? => false p s1.textfile? => false p s1.binaryfile? => true p s2.textfile? => false p s2.binaryfile? => false It currently only works with File#stat, but eventually, I'd like to make this work with IO#stat and File#lstat. But before I do this work, I'd like the group's feedback on what I've written so far. Thanks in advance. class File def self.stat(arg) Stat.new(arg) end class Stat private def self.isText(block) return (block.count("^ -~", "^\b\f\t\r\n") < (block.size / 3.0) && block.count("\x00") < 1) end public alias_method :__old_initialize, :initialize def initialize(arg) @item = arg __old_initialize(arg) end # The textfile? and binaryfile? methods are not inverses of each # other. Both return false if the item is not a file, or if the # item is a zero-length file. The "textness" or "binariness" of # an item can only be determined if it's a file that contains at # least one byte. def textfile? if self.zero? then return false end begin open(@item) { |file| block = file.read(self.blksize < self.size ? self.blksize : self.size) return self.class.isText(block) } rescue return false end end def binaryfile? if self.zero? then return false end begin open(@item) { |file| block = file.read(self.blksize < self.size ? self.blksize : self.size) return !self.class.isText(block) } rescue return false end end end # class Stat end # class File -- Lloyd Zusman ljz@asfast.com