2010-05-11 1 views

ответ

16

Файловый дескриптор, возможно, даже не подключен к файлу, а вместо этого подключен к сетевому сокету или к каналу, подключенному к стандартным выводам дочернего процесса.

Если вы хотите связать ручки с путями, которые открывает ваш код, используйте хэш и оператор fileno, , например.,

my %fileno2path; 

sub myopen { 
    my($path) = @_; 

    open my $fh, "<", $path or die "$0: open: $!"; 

    $fileno2path{fileno $fh} = $path; 
    $fh; 
} 

sub myclose { 
    my($fh) = @_; 
    delete $fileno2path{fileno $fh}; 
    close $fh or warn "$0: close: $!"; 
} 

sub path { 
    my($fh) = @_; 
    $fileno2path{fileno $fh}; 
} 
+0

Спасибо. Не то, что я хотел услышать, но более эффективное обходное решение. –

+0

@ sh-beta Добро пожаловать! Я надеюсь, что это помогает. –

5

Вы можете позвонить stat или IO::Handle::stat на дескрипторе - это даст вам устройство и индексный дескриптор файла, который вы открыли. С этим и небольшим волшебством операционной системы вы можете найти имя файла. Хорошо, может быть, много волшебства операционной системы.


Команда find имеет -inum вариант, чтобы найти файл с указанным номером инода. Вероятно, это будет не так эффективно, как кеширование пути при открытии файла, как рекомендует gbacon.

+0

Также допустимое обходное решение, хотя и медленное (как вы упомянули). –

6

Кто может искать лучший способ найти имя файла из дескриптора или дескриптора файла:

Я предпочел бы использовать находку -inum, если таковые имеются. Или, как насчет использования следующим образом, всегда - любые недостатки, кроме совместимых с unix/linux!

my $filename='/tmp/tmp.txt'; 
open my $fh, '>', $filename; 
my $fd = fileno $fh; 
print readlink("/proc/$$/fd/$fd"); 
+0

Вы также можете использовать 'fileno $ {^ LAST_FH}', если у вас нет дескриптора файла (например, вы используете '<>'). –

+0

Это совместимая с Linux, не совместимая с Unix. – tripleee

Смежные вопросы