【问题标题】:How do I determine whether a Perl file handle is a read or write handle?如何确定 Perl 文件句柄是读句柄还是写句柄?
【发布时间】:2009-03-23 04:15:09
【问题描述】:

给你一个IO::File 对象或一个typeglob(\*STDOUTSymbol::symbol_to_ref("main::FH"));您将如何确定它是读句柄还是写句柄?无法扩展接口以传递此信息(我正在覆盖close 以在实际关闭之前添加对flushsync 的调用)。

目前我正在尝试flushsync 文件句柄并忽略错误"Invalid argument"(这是我尝试flushsync 读取文件句柄时得到的):

eval { $fh->flush; 1 } or do {
        #this seems to exclude flushes on read handles
        unless ($! =~ /Invalid argument/) {
                croak "could not flush $fh: $!";
        }
};

eval { $fh->sync; 1 } or do {
        #this seems to exclude syncs on read handles
        unless ($! =~ /Invalid argument/) {
                croak "could not sync $fh: $!";
        }
};

【问题讨论】:

标签: perl filehandle


【解决方案1】:

查看 fcntl 选项。也许F_GETFLO_ACCMODE

编辑:我在午餐时做了一些谷歌搜索和玩,这里有一些可能不可移植的代码,但它适用于我的 Linux 机器,也可能适用于任何 Posix 系统(也许甚至 Cygwin,谁知道呢?)。

use strict;
use Fcntl;
use IO::File;

my $file;
my %modes = ( 0 => 'Read only', 1 => 'Write only', 2 => 'Read / Write' );

sub open_type {
    my $fh = shift;
    my $mode = fcntl($fh, F_GETFL, 0);
    print "File is: " . $modes{$mode & 3} . "\n";
}

print "out\n";
$file = new IO::File();
$file->open('> /tmp/out');
open_type($file);

print "\n";

print "in\n";
$file = new IO::File();
$file->open('< /etc/passwd');
open_type($file);

print "\n";

print "both\n";
$file = new IO::File();
$file->open('+< /tmp/out');
open_type($file);

示例输出:

$ perl test.pl 
out
File is: Write only

in
File is: Read only

both
File is: Read / Write

【讨论】:

  • 看起来 fcntl 是特定于操作系统的,但如果它适用于给定的操作系统,我可能只是基于操作系统构建一个调度散列,如果当前操作系统不在,我可能会回退到我当前的代码调度哈希。
  • 您可以使用O_RDONLY | O_RDWR | O_WRONLY 而不是硬编码“3”,但这些常量不太可能改变,因为它们已经有 20 年没有改变了。尽管如此,它使代码更具可读性。
  • 我可以访问 OS X、Linux、FreeBSD 和 WinXP;如果它适用于所有这些,那么这可能就是答案。
  • 它似乎适用于 IO::File 对象,但不适用于 typeglob,是时候看看如何将 typeglob 升级为 IO::File。
  • 显然我正在破解,它似乎对 typeglobs 工作得很好,STDIN 和 STDOUT 似乎被标记为读/写。当我使用一个文件时,我打开它就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-13
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
相关资源
最近更新 更多