【问题标题】:How to read and write a file, syntax wrong如何读写文件,语法错误
【发布时间】:2012-07-21 10:12:30
【问题描述】:
我最终让我的脚本将我想要进行的新更改附加到文件末尾而不是实际文件中。
open (INCONFIG, "+<$text") or die $!;
@config = <INCONFIG>;
foreach(@config)
{
if ( $_ =~ m/$checker/ )
{
$_ = $somethingnew;
}
print INCONFIG $_;
}
close INCONFIG or die;
最终我想再次重写整个文本,但如果它符合搜索条件,则修改某些字符串。但到目前为止,它只将整个文件的另一个副本(带有更改)附加到旧文件的底部。
我知道我可以关闭文件,并使用另一个写入文件-句柄并解析它。但希望能够了解我做错了什么,以及如何解决它。
【问题讨论】:
标签:
perl
file
file-io
handler
【解决方案1】:
据我了解open,对文本文件使用读/写访问权限并不是一个好主意。毕竟文件只是一个字节流:用不同长度的东西更新文件的一部分是令人头疼的东西;-)
这是我的方法:尝试模拟 perl 的 -i "inplace" 开关。所以基本上我们写入一个备份文件,稍后我们将对其进行重命名。 (在 *nix 系统上,打开文件句柄可以保持已删除的文件可用,因此我们没有创建新文件。无论如何,让我们这样做吧。)
my $filename = ...;
my $tempfile = "$filename.tmp";
open my $inFile, '<', $filename or die $!;
open my $outFile, '>', $tempfile or die $!;
while (my $line = <$inFile>) {
$line = doWeirdSubstitutions($line);
print $outFile $line;
}
close $inFile or die $!;
close $outFile or die $!;
rename $tempfile, $filename
or die "rename failed: $!"; # will break under weird circumstances.
# delete temp file
unlink $tempfile or die $!;
未经测试但显而易见的代码。这对您的问题有帮助吗?
【解决方案2】:
您的问题是对 Mixing Reads and Writes。
您真正想要做的是将旧文件复制到新文件,然后在事后重命名。这在 daxim 提到的perlfaq5 中有讨论。此外,还有专门用于安全执行此操作的完整模块,例如 File::AtomicWrite。这些有助于解决您的程序中止并留下一个被破坏的文件的问题。
【解决方案3】:
正如其他人指出的那样,有更好的方法:)
但是如果你真的想用+<读写,你应该记住,读完文件后,你就在文件的末尾……这说明你的输出是附加在原始内容之后的.
你需要做的是将文件指针重置到文件的开头,使用seek:
seek(INCONFIG ,0,0);
那就开始写吧……
【解决方案4】:
perlopentut 说这是关于混合读写
事实上,在更新文件时,除非您正在处理
二进制文件,如上面的 WTMP 案例,你可能不想使用
这种更新方式。相反,Perl 的 -i 标志出现在
救援。
另一种方法是使用Tie::File 模块。代码简化为:
tie my @config, 'Tie::File', $text or die $!;
s/$checker/$somethingnew/g for @config;
但是记住在修改文件之前备份文件,直到你调试了你的程序。