Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在perl中读取和写入现有文件_Perl - Fatal编程技术网

在perl中读取和写入现有文件

在perl中读取和写入现有文件,perl,Perl,我想使用perl对现有文件进行读写 有谁能告诉我,为了达到这个目的,我必须使用什么模式: 我对以下可用的模式感到困惑。 我尝试了+>,但没有写入文件 mode operand create truncate read < write > ✓ ✓ append >> ✓ mode operand create truncate read/write +< read/write +>

我想使用perl对现有文件进行读写

有谁能告诉我,为了达到这个目的,我必须使用什么模式: 我对以下可用的模式感到困惑。 我尝试了
+>
,但没有写入文件

mode operand create truncate 
read     <   
write    >    ✓      ✓ 
append  >>    ✓  

mode       operand create truncate 
read/write  +<   
read/write  +>       ✓      ✓ 
read/append +>>      ✓  
我想在两者之间插入一行,如:

one
two
three
four
从中,您有两个直接的问题:

+<几乎总是读/写更新的首选模式,+>模式将首先关闭文件

您通常不能使用读写模式来更新文本文件, 因为它们有可变长度的记录

更一般地说,在试图在文件中间插入数据时有一个设计问题——文本文件不能这样工作。最简单的方法是:

  • 将整个文件读入内存,然后修改后写入文件
  • 逐行读取输入文件,修改后将输出写入另一个文件。然后删除原始文件并将新文件重命名为旧名称
  • 1) 是最简单的,但是2)如果文件很大,内存效率会更高

    编辑:还有。它通过在幕后为您实现2)来实现这一点。然而,我个人更愿意坚持自己做。这似乎比它的价值更令人困惑。

    从中,您有两个直接的问题:

    +<几乎总是读/写更新的首选模式,+>模式将首先关闭文件

    您通常不能使用读写模式来更新文本文件, 因为它们有可变长度的记录

    更一般地说,在试图在文件中间插入数据时有一个设计问题——文本文件不能这样工作。最简单的方法是:

  • 将整个文件读入内存,然后修改后写入文件
  • 逐行读取输入文件,修改后将输出写入另一个文件。然后删除原始文件并将新文件重命名为旧名称
  • 1) 是最简单的,但是2)如果文件很大,内存效率会更高


    编辑:还有。它通过在幕后为您实现2)来实现这一点。然而,我个人更愿意坚持自己做。这似乎比它的价值更令人困惑。

    就地文件插入可能有点困难,因为必须移动数据。有关如何以其他方式实现目标(首选),请参见

    但是,为了就地插入:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my $file = 'input';
    open my $fh, '+<', $file or die "Failed to open $file: $!";
    
    my $pos, @remaining_lines;
    while (<$fh>) {
        if ($pos) {
            push @remaining_lines, $_;
        }
        elsif (m{^two$/$}) {
            $pos = tell;
        }
    }
    
    my $word = 'three';
    seek $fh, $pos, 0;
    print $fh $word, $/, @remaining_lines;
    
    #/usr/bin/env perl
    严格使用;
    使用警告;
    my$file='input';
    
    打开我的$fh,“+就地文件插入可能有点困难,因为必须移动数据。有关如何以其他方式实现目标(首选),请参见

    但是,为了就地插入:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my $file = 'input';
    open my $fh, '+<', $file or die "Failed to open $file: $!";
    
    my $pos, @remaining_lines;
    while (<$fh>) {
        if ($pos) {
            push @remaining_lines, $_;
        }
        elsif (m{^two$/$}) {
            $pos = tell;
        }
    }
    
    my $word = 'three';
    seek $fh, $pos, 0;
    print $fh $word, $/, @remaining_lines;
    
    #/usr/bin/env perl
    严格使用;
    使用警告;
    my$file='input';
    
    打开我的$fh,“+看看perlopentut
    有什么要说的。结论是,没有一种混合模式是理想的,就地编辑模式(使用
    $^I
    )是更好的解决方案

    对于这个特殊的问题,我推荐使用模块,它允许您将文件视为一个简单的数组

    例如,要在示例数据中插入行
    three
    ,请编写

    use strict;
    use warnings;
    
    use Tie::File;
    
    tie my @file, 'Tie::File', 'myfile.txt' or die $!;
    
    splice @file, 2, 0, 'three';
    
    untie @file or die $!;
    

    看看perlopentut
    有什么要说的。结论是,没有一种混合模式是理想的,就地编辑模式(使用
    $^I
    )是更好的解决方案

    对于这个特殊的问题,我推荐使用模块,它允许您将文件视为一个简单的数组

    例如,要在示例数据中插入行
    three
    ,请编写

    use strict;
    use warnings;
    
    use Tie::File;
    
    tie my @file, 'Tie::File', 'myfile.txt' or die $!;
    
    splice @file, 2, 0, 'three';
    
    untie @file or die $!;
    

    感谢您为这个很少使用的功能提供了一个很好的说明。感谢您为这个很少使用的功能提供了一个很好的说明。这是一个很好的解决方案。不过,缺点是,每次插入文件都是立即进行的,而且成本相当高,因为在这一点之后,整个文件都必须移动。如果必须进行大量插入,请查看Tie::File的延迟写入特性——这是一个很好的解决方案。不过,缺点是,每次插入文件都是立即进行的,而且成本相当高,因为在这一点之后,整个文件都必须移动。如果必须进行大量插入,请查看Tie::File的延迟写入特性-