【问题标题】:When opening a file in perl, how can I automatically use STDIN/OUT if the file name is "-"?在 perl 中打开文件时,如果文件名为“-”,如何自动使用 STDIN/OUT?
【发布时间】:2010-04-26 13:07:23
【问题描述】:

我有一个接受输入和输出文件参数的 perl 程序,我想支持使用 "-" 指定标准输入/输出的约定。问题是我不能只打开文件名,因为open(my $input, '<', '-') 打开的是一个名为- 的文件,而不是标准输入。所以我必须这样做:

my $input_fh;
if ($input_filename eq '-') {
    # Special case: get the stdin handle
    $input_fh = *STDIN{IO};
}
else {
    # Standard case: open the file
    open($input_fh, '<', $input_filename);
}

对于输出文件也是如此。有没有办法在不自己测试特殊情况的情况下做到这一点?我知道我可以破解 ARGV 文件句柄来为输入执行此操作,但这不适用于输出。

编辑:我被告知 open 的 2 参数形式实际上具有我正在寻找的魔力。不幸的是,它还做了一些创造性的解释,以便将文件名与第二个参数中的模式分开。我猜open 的 3 参数形式是 100% 无魔法的——它总是会打开你告诉它的 exact 文件。我在问我是否可以为 "-" 设置一个例外,同时仍然明确地处理所有其他文件名。

我应该将我的代码从上面粘贴到子程序/模块中并停止抱怨吗?

【问题讨论】:

  • 事实证明,没有一种内置的方式可以同时变魔术和变魔术。所以我想我会自己写。

标签: perl io


【解决方案1】:

改用双参数形式:

open ($input_fh, "< " . $input_filename);

来自man perlfunc

在 2 参数(和 1 参数)形式中打开“'-'”打开 STDIN 并打开“'>-'”会打开 STDOUT。

请注意,&lt; 模式在 2 参数形式中是可选的,因此 "&lt; -" 是完全合法的。

【讨论】:

  • 在文件以&lt;&gt; 开头的情况下,双参数打开是否不会出现歧义问题?还是您在上面显示的串联 ('&lt;' . $filename) 总是消除歧义?
  • @Ryan 我不知道这是一个要求。只需在模式和文件名之间引入一个空格,如编辑后的答案所示。
  • 好吧,理论上你可以有一个名称以空格开头的文件。问题是 2 参数 open 无论如何都必须解释文件名。我喜欢 3-arg open 的安全性,因为无论如何它都会按字面意思获取文件名。
  • @Ryan 除了“-”的情况下,您不能按字面意思获取文件名,对吗? :-) 也许你可以引用空格。
  • 我猜 2-arg open 是我提出的问题的最佳答案。我将使用的解决方案是将我想要的行为简单地封装到我自己的实用程序子例程中。
【解决方案2】:

我想我找到了我要找的东西。有一个名为 IO::All 的漂亮模块可以满足我的需求,甚至更多。

对于 Debian/Ubuntu/类似用户,该软件包称为 libio-all-perl。我想让它成为“apt:libio-all-perl”的可点击链接,但显然这里只允许使用 http 链接。


编辑

还有Iterator::Diamond,它实现了我所要求的可调魔法。它是为替换“钻石”运算符&lt;&gt; 而设计的,但如果仅使用单个文件调用它可能会执行我所要求的操作(可能会产生一些开销,但谁在乎呢?)。

【讨论】:

  • 实际上,这些模块都没有提供与简单文件句柄的完全兼容性。
猜你喜欢
  • 2011-01-28
  • 2011-03-16
  • 2012-03-25
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多