Getting the file name from a File::Stat object?

Is there a way to get the file name from a File::Stat object?

Thanks in advance.

···


Lloyd Zusman
ljz@asfast.com

Only way is to search files which have the inode number File::Stat#ino.
File::Stat represents status of an inode and an inode may be associated
many file names.

% mkdir foo
% cd foo
% touch a
% ln a b
% ln a c
% ls -i
2032361 a 2032361 b 2032361 c
% ruby -e ‘s = %w(a b c).map{|i| File.stat(i)}; p [s[0]==s[1], s[1]==s[2]]’
[true, true]
% touch d
% ls -i
2032361 a 2032361 b 2032361 c 2032364 d
% find . -inum 2032361
./a
./b
./c
% ruby -r find -e ‘a = File.stat(“a”); Find.find("."){|i| puts i if File.stat(i).ino == a.ino}’
./c
./b
./a
%

But you might need to do Find.find("/") instead of Find.find(".").

– Gotoken

···

At Fri, 9 Aug 2002 22:46:32 +0900, Lloyd Zusman wrote:

Is there a way to get the file name from a File::Stat object?

GOTO Kentaro gotoken@notwork.org writes:

Is there a way to get the file name from a File::Stat object?

Only way is to search files which have the inode number File::Stat#ino.
File::Stat represents status of an inode and an inode may be associated
many file names.

[ … ]

Thank you very much.

I was hoping that I didn’t have to do it via inodes. Oh well … [sigh]

Actually, I just want to retrieve the initial argument, exactly as
specified.

For that purpose, I know I can always use a subclass, like this:

class MyStat < File::Stat
attr_reader :item
def initialize(arg)
@item = arg
super(arg)
end
end

stat = MyStat.new(“file.name”)
p stat.item

output: “file.name

But I was hoping I didn’t need to rely on a subclass, so that I could
also get the same behavior from File.stat, etc. Like I said above …
oh well …

Thanks again.

···

At Fri, 9 Aug 2002 22:46:32 +0900, > Lloyd Zusman wrote:


Lloyd Zusman
ljz@asfast.com

You can redefine File.stat as follows, however, I don’t recommend this
because File::stat is not API for a file but just for a inode. For
example, File::stat can represent a file which has been deleted already.

class File
class << self
alias_method(:stat, :stat)

  def stat(arg)
    Stat.new(arg)
  end
end

class Stat
  attr_reader :item
  def initialize(arg)
    @item = arg
  end
end

end

fn = "file.name"
File.open(fn,“a”).close # creat
p File.stat(fn).item
p File::Stat.new(fn).item

f = open(fn)
File::delete(fn)
p File.exists?(fn)
p f.stat
p $stdout.stat

– Gotoken

···

At Fri, 9 Aug 2002 23:24:41 +0900, Lloyd Zusman wrote:

For that purpose, I know I can always use a subclass, like this:

class MyStat < File::Stat
attr_reader :item
def initialize(arg)
@item = arg
super(arg)
end
end

stat = MyStat.new(“file.name”)
p stat.item

output: “file.name

But I was hoping I didn’t need to rely on a subclass, so that I could
also get the same behavior from File.stat, etc. Like I said above …
oh well …

Maybe you want to say: File::Stat is not an API for a filename but just
for a file.

A file and an inode, for most purposes, are the same thing. In particular,
the inode is the entry point of the file, contains everything about it
except filenames and actual file data, and is the sole source for pointers
to the file data. Files are uniquely identified by their inode number.

···

On Sat, 10 Aug 2002, GOTO Kentaro wrote:

You can redefine File.stat as follows, however, I don’t recommend this
because File::stat is not API for a file but just for a inode. For
example, File::stat can represent a file which has been deleted already.


Mathieu Bouchard http://artengine.ca/matju

GOTO Kentaro gotoken@notwork.org writes:

For that purpose, I know I can always use a subclass, like this:

[ … etc. … ]

You can redefine File.stat as follows, however, I don’t recommend this
because File::stat is not API for a file but just for a inode. For
example, File::stat can represent a file which has been deleted already.

[ … etc. … ]

I totally agree with you, in the general case for the use of File::Stat.
However, I have a specific need for ANY of the valid filenames that
refer to the inode in question. It doesn’t matter which of the names I
use, as long as it’s ONE of them.

I want to use that name in order to implement a "File::Stat#textfile?"
method that returns true if the item in question is a file which
contains non-binary data. In order to implement the “textfile?” method,
I have to have a filename that I can pass to an “open” method call,
as follows:

class File

def self.stat(arg)
  Stat.new(arg)
end

class Stat

  alias_method :__old_initialize, :initialize
  attr_reader :item

  def initialize(arg)
    @item = arg
    __old_initialize(arg)
  end

  # New method that returns "true" if the item is a file
  # that only contains text data (i.e., non-"binary" data).

  def textfile?
    begin
      open(@item) {
        >file>
        block = file.read(self.blksize < self.size ?
                          self.blksize : self.size)
        return block.size == 0 ||
               ((block.count("^ -~", "^\b\f\t\r\n") / block.size) < 0.3 &&
                block.count("\x00") < 1)
      }
    rescue
      return false
    end
  end

end

end

s = File.stat("/etc/fstab")
t = File.stat("/bin/sh")

p s.textfile? # outputs true' p t.textfile? # outputsfalse’

···

At Fri, 9 Aug 2002 23:24:41 +0900, > Lloyd Zusman wrote:


Lloyd Zusman
ljz@asfast.com

You can redefine File.stat as follows, however, I don’t recommend this
because File::stat is not API for a file but just for a inode. For
example, File::stat can represent a file which has been deleted already.

Maybe you want to say: File::Stat is not an API for a filename but just
for a file.

Yes. Sorry for inaccuracy.

A file and an inode, for most purposes, are the same thing. In particular,
the inode is the entry point of the file, contains everything about it
except filenames and actual file data, and is the sole source for pointers
to the file data. Files are uniquely identified by their inode number.

Thanks you for good explanation.

I leaned these things from Richard Stevens’s “Advanced Programming in
the UNIX Environment”. This is really nice book.
http://www.aw.com/catalog/academic/product/1,4096,0201563177,00.html

– Gotoken

···

At Sat, 10 Aug 2002 00:57:05 +0900, Mathieu Bouchard wrote:

On Sat, 10 Aug 2002, GOTO Kentaro wrote:

I see. But why not File#textfile?. For normal files, you can
implement File#textfile? straightforwardly.

class File
def textfile?
pos = pos()
self.pos = 0
begin
_critical = Thread.critical
Thread.critical = true
value = # your code to decide
value
ensure
self.pos = pos
Thread.critical = _critical
end
end
end

– Gotoken

···

At Sat, 10 Aug 2002 03:56:48 +0900, Lloyd Zusman wrote:

I want to use that name in order to implement a "File::Stat#textfile?"
method that returns true if the item in question is a file which
contains non-binary data. In order to implement the “textfile?” method,
I have to have a filename that I can pass to an “open” method call,
as follows:

GOTO Kentaro gotoken@notwork.org writes:

I want to use that name in order to implement a "File::Stat#textfile?"
method that returns true if the item in question is a file which
contains non-binary data. In order to implement the “textfile?” method,
I have to have a filename that I can pass to an “open” method call,
as follows:

I see. But why not File#textfile?. For normal files, you can
implement File#textfile? straightforwardly.

[ … etc. … ]

Yes, I could indeed do it that way, but the “File::Stat#textfile?” method
seems similar to the “File::Stat#file?” method, and to me, it seems
more logical for that method to belong within the File::Stat class.

After all, it’s only a Unix-specific implementation detail that requires
us to open the file and read a block of data in order to determine
whether we have a text file. There might be other operating systems
that supply that information in a different manner. The
"File::Stat#textfile?" method would then not need to do an “open” or a
"read" under that OS.

Therefore, to me, the “textfile?” method seems to just be returning an
attribute of a file, just like “size”, “blksize”, “ino”, “dev”, and
other information that File::Stat returns.

But I guess that this is a matter of personal taste.

···

At Sat, 10 Aug 2002 03:56:48 +0900, > Lloyd Zusman wrote:


Lloyd Zusman
ljz@asfast.com