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

发布于 2024-12-11 22:38:03 字数 166 浏览 0 评论 0原文

在 ruby​​ 中...

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

有没有办法从该对象获取文件名,甚至获取文件对象?

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

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫相离 2024-12-18 22:38:03

关于 how to get a the filename in C 有一个类似的问题,我在这里用 ruby​​ 的方式给出这个问题的答案。

在 Linux 中获取文件名

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

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

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

获取不知道文件名的 File 对象

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

File.for_fd(io.fileno)

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

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

我浏览了 ruby​​-1.9.2 源代码。在纯 ruby​​ 中似乎无法在创建文件对象后操作路径。

获取知道文件名的 File 对象

可以在 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);

}

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

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

读取链接也可以放入 File#for_fd_with_filename 定义中。这个例子只是为了展示它是如何工作的。

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.

Getting the filename in Linux

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

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.

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:

File.for_fd(io.fileno)

Unfortunely this File object does not know the filename.

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.

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.

#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.

森林很绿却致人迷途 2024-12-18 22:38:03

如果您确定 IO 对象代表一个文件,您可以尝试类似的操作

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

查看 File#path 的文档

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

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

See documentation for File#path

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文