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