如何从ruby中的IO对象获取文件名

[英]How to get a filename from an IO object in ruby


In ruby...

I have an IO object created by an external process, which I need to get the file name from. However I only seem to be able to get the File descriptor (3), which is not very useful to me.

我有一个由外部进程创建的IO对象,我需要从中获取文件名。但是我似乎只能得到文件描述符(3),这对我来说不是很有用。

Is there a way to get the filename from this object or even to get a File Object?

有没有办法从这个对象获取文件名甚至获取文件对象?

I am getting the IO object from notifier. So this may be a way of getting the file path as well?

我从通知程序获取IO对象。那么这可能是一种获取文件路径的方法呢?

2 个解决方案

#1


5  

There is a similar question on how to get a the filename in C, I will present here the answer to this question in a ruby way.

有关如何在C中获取文件名的类似问题,我将以红宝石的方式呈现此问题的答案。

Getting the filename in Linux

Suppose io is your IO Object. The following code gives you the filename.

假设io是你的IO对象。以下代码为您提供文件名。

File.readlink("/proc/self/fd/#{io.fileno}")

This does not work for example if the file was removed after the io object was created for it. With this solution you have the filename, but not an File object.

例如,如果在为其创建io对象后删除了文件,则这不起作用。使用此解决方案,您可以使用文件名,但不能使用File对象。

Getting a File object which does not know the filename

The method IO#for_fd can create an IO and it's subclasses for any given integer filedescriptor. Your get your File object for your fd by doing:

IO#for_fd方法可以为任何给定的整数文件描述符创建IO和它的子类。通过执行以下操作,获取fd的File对象:

File.for_fd(io.fileno)

Unfortunely this File object does not know the filename.

不幸的是,这个File对象不知道文件名。

File.for_fd(io.fileno).path # => nil

I scanned through the ruby-1.9.2 sources. There seems to be no way in pure ruby to manipulate the path after the file object was created.

我浏览了ruby-1.9.2来源。在创建文件对象之后,纯ruby中似乎没有办法操纵路径。

Getting a File object which does know the filename

An extension to ruby can be created in C which first calls File#for_fd and afterwards manipulates the Files internal data structures. This sourcecode does work for ruby-1.9.2, for other versions of ruby it may has to be adjustet.

可以在C中创建ruby的扩展,它首先调用File#for_fd,然后操作Files内部数据结构。这个源代码适用于ruby-1.9.2,对于其他版本的ruby,它可能必须调整。

#include "ruby.h"
#include "ruby/io.h"

VALUE file_fd_filename(VALUE self, VALUE fd, VALUE filename) {
    VALUE file= rb_funcall3(self, rb_intern("for_fd"), 1, &fd);
    rb_io_t *fptr= RFILE(rb_io_taint_check(file))->fptr;
    fptr->pathv= rb_str_dup(filename);
    return file;
}

void Init_filename() {

    rb_define_singleton_method(rb_cFile, "for_fd_with_filename", file_fd_filename, 2);

}

Now you can do after compiling:

现在你可以在编译后做:

require "./filename"
f= File.for_fd_with_filename(io.fileno, File.readlink("/proc/self/fd/#{io.fileno}"))
f.path # => the filename

The readlink could also be put into the File#for_fd_with_filename definiton. This examples is just to show how it works.

readlink也可以放入File#for_fd_with_filename definiton。这个例子只是为了说明它是如何工作的。

#2


0  

If you are sure that the IO object represents a File you could try something like this

如果您确定IO对象代表文件,您可以尝试这样的事情

path = io.path if io.respond_to?(:path)

See documentation for File#path

请参阅File#path的文档

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2011/10/25/ecce70782bacded2b742ba5c9bce2f41.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告