【问题标题】:Perl Filehandle Open Truncates the FilePerl Filehandle Open 截断文件
【发布时间】:2013-11-18 17:50:28
【问题描述】:

我正在编写我的第一个 Perl 程序,它非常棒。我很高兴地说,大部分情况下一切正常,搜索这个网站帮助解决了我的大部分问题。

我正在处理一个由空格分隔值组成的大文件。我过滤文件以仅在其中一列中显示具有特定值的行,并将过滤后的数据输出到新文件。然后我尝试将该文件的所有行推入一个数组以用于循环。这是一些代码:

my @orig_file_lines = <ORIG_FILE>;
open MAKE_NEW_FILE, '>', 'newfile.dat' or die "Couldn't open newfile.dat!";
&make_new_file(\@orig_file_lines);   ##Creates a new, filtered newfile.dat
open NEW, "newfile.dat" or die "Couldn't open newfile.dat!";
my @lines;
while(<NEW>){
 push(@lines,$_);
}
printf("%s\n", $lines[$#lines]);  ##Should print entirety of last line of newfile.dat

问题是双重的:1.这里$#lines = 24500当新创建的文件(newfile.dat)实际上有24503行(所以应该是24502),2.printf语句返回截断的24500行,切割过早地离开那条线大约两列。

每隔一行,例如$lines[0-24499],即使它比 $lines[24500] 宽,也会成功打印整行,因此该特定行的长度(它们都很长)不是问题。但这几乎就好像数组以某种方式变得太大了,因为它切断了一行的一部分,然后切断了接下来的两行。如果是这样,我该如何应对?

【问题讨论】:

  • 好吧,我没有在这里展示它,但我实际上将它打印到了一个文件中,所以它不是终端截断。此外,$lines[24501] 和 $lines[24502] 仍未计算在内。
  • 如果我打印 $#lines,我得到 24500。文件中有我想要的 24503 行。所以打印 $lines[0] 给了我第一行的全部内容, $lines[24999] 给了我第 24500 行的全部内容,但是 $lines[24500] 给了我第 24501 行的大部分内容,但不是全部。 $lines[24501] 给我一个错误,因为它是空的,但它应该包含第 24502 行。同样适用于 $lines[24502]。
  • 你如何定义“线条”?当一些被 crlf 终止而一些被 lf 终止时,可能会发生这种情况;以及不同工具基于此解释“线条”的方式。
  • 'lines' 是从上面代码的 5-8 行中的文件句柄创建的数组。理论上,数组的每个元素都应该有一个单独的行,以'\n'结尾。我在那里使用了 while 循环,因为我对解决方案的搜索表明它对于大文件来说是一个更好的约定。而我最初使用的是@lines=

标签: arrays perl truncate filehandle


【解决方案1】:

您好像忘记在使用 NEW 打开同一个文件之前关闭 MAKE_NEW_FILE。

需要注意的其他几点:

  • &amp;function 语法大多被弃用,因为它绕过原型检查。

  • 我相信您使用的是use warnings;use strict;

  • 我注意到您有一个开放的两个参数和一个三个参数open。尽管两者都是合法的,但它们具有不同的思维方式,这使得将它们一起使用会使程序员感到困惑。我会保留三个论点,因为我认为它更容易理解(除非你正在玩代码高尔夫)

【讨论】:

  • 感谢您的回复。你说得对,我忘了关闭 MAKE_NEW_FILE,我必须解决这个问题。还有另一种调用子程序的方法吗?除了 &subroutinecall(); 之外,我不知道任何其他方法。是的,他们都在! :) 好点,我将其更改为 3 参数打开。
  • &amp;sub 语法经常被误用,就像 OP 所做的那样,但它没有被弃用,因为它提供了一个有用的功能:在忽略其原型的同时调用 sub。
  • 成功了!我知道这一定很愚蠢。注意自己,关闭你的文件句柄!非常感谢你。另外,我不知道您可以在没有“&”的情况下调用子例程!我刚刚阅读了“Learning Perl”,它告诉我要使用它。
  • @ikegami : 这就是为什么我说主要是贬值,因为有时你想要那种语法,但我愿意在第一个程序中打赌。
  • 没有理由避免它,也没有被取代。你可以使用\&amp;foo-&gt;(@a) 而不是&amp;foo(@a),但你为什么要这样做?
猜你喜欢
  • 1970-01-01
  • 2012-04-16
  • 1970-01-01
  • 2018-01-09
  • 2011-12-04
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多