Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从ruby中的IO对象获取文件名_Ruby_Io - Fatal编程技术网

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

如何从ruby中的IO对象获取文件名,ruby,io,Ruby,Io,用红宝石 我有一个由外部进程创建的IO对象,我需要从中获取文件名。 然而,我似乎只能得到文件描述符(3),这对我来说不是很有用 有没有办法从这个对象获取文件名,或者甚至获取文件对象 我正在从通知程序获取IO对象。因此,这可能也是获取文件路径的一种方法?如果您确定IO对象代表一个文件,您可以尝试以下方法 path = io.path if io.respond_to?(:path) 上有一个类似的问题,我将在这里以ruby的方式给出这个问题的答案 在Linux中获取文件名 假设io是您的io对象

用红宝石

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

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


我正在从通知程序获取IO对象。因此,这可能也是获取文件路径的一种方法?

如果您确定IO对象代表一个文件,您可以尝试以下方法

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

上有一个类似的问题,我将在这里以ruby的方式给出这个问题的答案

在Linux中获取文件名 假设
io
是您的io对象。下面的代码提供了文件名

File.readlink("/proc/self/fd/#{io.fileno}")
File.for_fd(io.fileno).path # => nil
例如,如果文件是在为其创建io对象后删除的,则此操作不起作用。使用此解决方案,您有文件名,但没有文件对象

获取不知道文件名的文件对象 方法
IO#for_fd
可以为任何给定的整数文件描述符创建IO及其子类。通过执行以下操作获取fd的文件对象:

File.for_fd(io.fileno)
不幸的是,这个文件对象不知道文件名

File.readlink("/proc/self/fd/#{io.fileno}")
File.for_fd(io.fileno).path # => nil
我浏览了ruby-1.9.2的源代码。在纯ruby中,似乎没有办法在创建文件对象之后操作路径

获取不知道文件名的文件对象 可以在C中创建ruby的扩展,该扩展首先调用
File#for_fd
,然后处理文件内部数据结构。此源代码适用于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);

}
现在,您可以在编译后执行以下操作:

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

readlink也可以放入文件名为definiton的文件中。这个例子只是为了说明它是如何工作的。

在BSD上不起作用,而且扩展到OS X上也不起作用,因为它们没有一个
/proc
伪文件系统(是的,有procfs,但在FreeBSD中默认情况下没有安装它——除了被逐步淘汰之外——而且在OS X下安装它绝对不简单)。IO对象不代表文件对象,它代表IO对象。我想从中获取一个文件对象。由于io不响应路径,上述操作将不起作用。如果有人从您下方重命名文件,则此操作在
文件
对象上也不起作用--
f.path
将返回旧路径。