2017-01-07 15 views
0

Я пишу файл с помощью Perl. Есть ситуация, когда после написания 4 строк мне нужно вернуться 4 строки и написать что-то, а затем вернуться к концу файла и снова начать писать. Есть ли способ переместить строку позиции дескриптора файла?Как я могу изменить строку указателя позиции 4 строки назад при записи файла с помощью perl?

+0

Re: 'Есть ли способ переместить строку позиции дескриптора файла? Нет. Http://xyproblem.info/ –

ответ

4

Вы можете перемещать позицию по номеру seek. Однако файлы не имеют индексов строк, поэтому вам придется либо отслеживать позицию линий (полученную с использованием tell), как вы их пишете, либо открываете их, используя подход, подобный File::ReadBackwards.

Что вы хотите сделать с содержимым файла, находящегося между позицией, к которой вы хотите, и к концу файла? Вам нужно будет скопировать его, если вы хотите вставить строки, или truncate, если вы хотите его удалить.

Если вы можете сохранить буфер вместо него.

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

Вы можете использовать Tie::File делать все волшебство для Вас. Это ties файл в массив, чтобы каждая строка была представлена ​​элементом массива. Tying - механизм, который очень мощный, но, кажется, считается очень продвинутым в настоящее время.

Это позволяет использовать обычные операции с массивами, такие как push и unshift, или даже splice на файл. Вам не нужно ставить символы новой строки. Он автоматически использует $/.

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'; 

Файл теперь будет содержать:

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

1) Я говорю расширенный, но на самом деле я имею в виду, что она не получила широкого распространения и не понимал в настоящее время. Существует не так много учебных материалов, которые охватывают tie, и исходный прецедент доступа к файлам базы данных довольно устарел и. Я бы сказал, что многие люди никогда не слышали об этом, хотя это мощная функция.

+0

Я не уверен, что назвал бы это продвинутым, как нечто, что есть (почти?), уникальный для perl. Значит, у вас есть люди, которые действительно не понимают эту концепцию. – Sobrique

+1

@Sobrique Я выбрал слово _advanced_, так как он вряд ли охвачен современными учебными ресурсами, и не так много распространенных случаев использования. Я согласен с тем, что он довольно уникален, хотя в последнее время я вспоминаю недавний разговор, в котором кто-то сказал, что у пары более свежих языков есть аналогичная функция, и что у нас это было в течение длительного времени. Но я не могу вспомнить, где это было, или какие языки. – simbabque

+1

Нет, правда. Поскольку ОО является обычным явлением - и, как правило, более понятная парадигма - необходимость «связывания» уменьшается. И, возможно, немного опасно иметь «волшебную» вещь, которая выглядит как обычная переменная. – Sobrique