2010-05-11 10 views

Répondre

16

Un descripteur de fichier n'est peut-être même pas connecté à un fichier mais à un socket réseau ou à un canal connecté à la sortie standard d'un processus enfant.

Si vous souhaitez associer des poignées à des chemins que votre code ouvre, utilisez un hachage et l'opérateur fileno, par exemple.,

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

Merci. Pas ce que je voulais entendre, mais la solution de contournement plus efficace. –

+0

@ sh-beta De rien! J'espère que ça aide. –

5

Vous pouvez appeler stat ou IO::Handle::stat sur un descripteur de fichier - qui vous donnera l'appareil et inode du fichier que vous avez ouvert. Avec cela et un peu de magie du système d'exploitation, vous pouvez trouver le nom de fichier. OK, peut-être beaucoup de magie du système d'exploitation.


La commande find a une option -inum pour trouver un fichier avec un numéro d'inode spécifié. Cela ne sera probablement pas aussi efficace que la mise en cache du chemin lorsque vous ouvrez le fichier, comme le recommande gbacon.

+0

Aussi une solution de contournement valide, bien que lente (comme vous l'avez mentionné). –

6

Celui qui pourrait être à la recherche d'une meilleure façon de trouver le nom du fichier de descripteur ou d'un fichier descripteur de fichier:

Je préférerais utiliser le -inum de trouver, le cas échéant. Ou, que diriez-vous d'utiliser la manière suivante, toujours - des inconvénients, sauf la compatibilité unix/linux!

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

Vous pouvez également utiliser 'fileno $ {^ LAST_FH}' si vous n'avez pas le handhandle à portée de main (par exemple, vous utilisez '<>'). –

+0

Ceci est compatible avec Linux et n'est généralement pas compatible Unix. – tripleee

Questions connexes