如何确定两个把手指向同一个文件

问题描述 投票:3回答:2

我想检查两个文件句柄是指同一个文件。为了做到这一点,我可以使用应用到每个文件句柄stat功能?提前致谢

my $file = 'C:\temp\file.txt');
open( TXT1, "> $file" );
open( TXT2, "> $file" );
print( "The handles refer to the same file!") if (\TXT1 eq \TXT2);
perl handler stat filehandler
2个回答
4
投票

不能在一般的(可移植的)来完成,†什么是可以理解的,一个“文件”句柄不必与文件的所有关联。有一两件事你可以做的是记录每个文件句柄的fileno

因此,打开文件时

my %filename_fileno;

open my $fh, '>', $file or die "Can't open $file: $!";

$filename_fileno{fileno $fh} = $file;

然后在需要的时候,你可以去查一下‡

say "Filename is: ", $filename_fileno{fileno $fh};

不要忘了从哈希删除的条目时该文件被关闭(是)

delete $filename_fileno{fileno $fh};
close $fh;

因此,这些应该是在实用功能。考虑到更多的照顾是必要的,因为在‡脚注概述,共此将使一个可爱的小模块。然后,一个也可以考虑延长(继承)相关的模块,如Path::Tiny

注意:您可以不写,从这样的单独文件句柄的文件。每个操作文件句柄跟踪下文件句柄的最后文件中,这样写道将由其他文件句柄揍中间写。

注意:使用词法文件句柄(my $fh),而不是水珠(FH),使用三个参数open,并经常检查open电话。


†在某些(大多数?)的Linux系统,你可以使用文件系统/proc

say readlink("/proc/$$/fd/" . fileno $fh);

和更多的(所有?)的Unix-Y系统可以使用(设备和)inode编号

say for (stat $fh)[0,1];

‡链接,这两个软(符号)和硬,可以用来改变数据和具有不同的名称。因此,我们可以有不同的文件名,但同样的“文件”(数据)。

在Windows系统上,检查的最佳方式this post给出,但对于其中一个将不得不使用其他答案的方法(解析输出),据我可以告诉硬链接的情况。

此外,不规范的名称,以及不同的资本化(对大小写不敏感的系统),在某些系统上的短/长文件名,(多?)......可以为同一个文件的不同名称。这是比较容易清理,使用模块,但需要添加。

在大多数(全部?)其他系统的inode的概念,任何可用的stat一样的功能,使这些非问题,因为设备+ inode的唯一指的是数据。

由于ikegami对这个意见。


2
投票

是,在某些系统+设备的组合,stat可以使用。

use File::stat;

my $st1 = stat($fh1)
   or die $!;
my $st2 = stat($fh2)
   or die $!;

say $st1->dev == $st2->dev && $st1->ino == $st2->ino ? "same" : "different";

值得注意的是,这不会对NTFS或FAT32,其中一个你似乎是使用工作。

你应该把你的程序保持其本身的轨道,但是这谈何容易。这是相当难以确定,如果两个路径指向同一个文件时,你有硬链接,软链接,与. / ..路径,资本/斜线差异,短/长名,常规/ UNC路径,股份等抗衡

例如,下面所有的路径可能是指同一个文件:

  • C:\Moo\Foo Bar.txt
  • C:\Hardlink\Foo Bar.txt
  • C:\Softlink\Foo Bar.txt
  • C:\.\Moo\Foo Bar.txt
  • C:\Baz\..\Moo\Foo Bar.txt
  • c:\moo\foo bar.txt
  • C:/Moo/Foo Bar.txt
  • C:\Moo\FOOBAR~1.TXT
  • \\?\C:\Moo\Foo Bar.txt
  • \\127.0.0.1\C$\Moo\Foo Bar.txt
  • Z:\Moo\Foo Bar.txt

所有但最后两个可以通过标准化处理。

© www.soinside.com 2019 - 2024. All rights reserved.