2017-01-07 2 views
0

Ich schreibe die Datei mit Perl. Es gibt eine Situation, wo nach dem Schreiben von 4 Zeilen, ich 4 Zeilen zurückgehen und etwas schreiben muss, dann zurück zum Ende der Datei kommen und wieder zu schreiben beginnen. Gibt es eine Möglichkeit, die Dateizugriffslinie zeilenweise zu verschieben?Wie kann ich die Dateizeigerposition 4 Zeilen zurück ändern, während ich die Datei mit Perl schreibe?

+0

Re: 'Gibt es eine Möglichkeit, Datei-Handle-Position Zeile weise zu verschieben?' Nein. Http://xyproduction.info/ –

Antwort

4

Sie können die Position tatsächlich mit seek verschieben. Dateien haben jedoch keine Indizes von Zeilen, so dass Sie entweder die Position der Zeilen verfolgen müssen (wie erhalten Sie mit tell), während Sie sie schreiben, oder entdecken Sie sie mit einem ähnlichen Ansatz wie File::ReadBackwards.

Was möchten Sie mit dem Inhalt der Datei tun, der zwischen der gesuchten Position und dem Ende der Datei liegt? Sie müssen es kopieren, wenn Sie Zeilen einfügen möchten, oder truncate die Datei, wenn Sie sie löschen möchten.

Wenn Sie können, einen Puffer stattdessen beibehalten.

my @buf; 
while (...) { 
    if (...) { 
     splice(@buf, -4, 0, $line); # Insert the line 4 lines from the end. 
    } else { 
     push(@buf, $line);   # Append a line. 
    } 

    print($fh shift(@buf)) while @buf > 4; 
} 

print($fh @buf); 
2

Sie können Tie::File verwenden Sie die ganze Magie zu tun. Es ties eine Datei in ein Array, so dass jede Zeile von einem Array-Element dargestellt wird. Tying ist ein Mechanismus, der sehr leistungsfähig ist, aber heutzutage als sehr fortgeschritten angesehen wird.

Das macht es möglich, normale Array-Operationen wie push und unshift oder sogar splice für die Datei zu verwenden. Sie müssen keine Zeilenumbrüche einfügen. Es verwendet $/ automatisch.

use Tie::File; 

tie my @file, 'Tie::File', 'foo.txt' or die $!; 

push @file, "Line 1"; 
push @file, "Line 2"; 
push @file, "Line 3"; 
push @file, "Line 4"; 
push @file, "Line 5"; 

# to overwrite 
$file[-4] = 'Line 6 overwrote line 2'; 

# to append 
$file[-3] .= ' and Line 7'; 

# to insert 
splice @file, -2, 0, 'Line 8'; 

Die Datei wird nun enthalten:

Line 1 
Line 6 overwrote line 2 
Line 3 and Line 7 
Line 8 
Line 4 
Line 5 

1) Ich sage fortgeschritten, aber wirklich meine ich, dass es nicht weit verbreitet ist, oder heutzutage verstanden. Es gibt nicht viele Lernmaterialien, die tie abdecken, und der ursprüngliche Anwendungsfall des Zugriffs auf Datenbankdateien ist ziemlich veraltet und. Ich würde sagen, viele Leute haben noch nie davon gehört, obwohl es ein starkes Feature ist.

+0

Ich bin mir nicht sicher, ich würde es als fortgeschritten bezeichnen, so viel wie (fast?) einzigartig für Perl. Das bedeutet, dass Sie Leute haben, die das Konzept nicht wirklich verstehen. – Sobrique

+1

@Sobrique Ich wählte das Wort _advanced_, da es in modernen Lernressourcen kaum abgedeckt ist, und es gibt nicht viele häufige Anwendungsfälle. Ich stimme zu, dass es ziemlich einzigartig ist, obwohl ich mich erinnere, kürzlich eine Rede zu sehen, in der jemand sagte, dass eine neuere Sprache jetzt eine ähnliche Funktion hat und dass wir sie schon lange haben. Aber ich kann mich nicht erinnern, wo das war oder welche Sprachen. – simbabque

+1

Nein, wahr genug. Da OO alltäglich ist - und im Allgemeinen ein besser verstandenes Paradigma - ist die Notwendigkeit von "tie" vermindert. Und es ist wohl ein bisschen gefährlich, ein "magisches" Ding zu haben, das wie eine normale Variable aussieht. – Sobrique

Verwandte Themen