Есть еще одна вещь, которую следует учитывать при такого рода операциях. Что вы делаете, если вы запутались при записи новых данных? Как вы собираетесь терпеть программу, которая усекает исходный файл, но не может полностью записать новые данные?
Вместо того, чтобы открывать дескриптор файла записи с тем же именем файла, используйте временный файл. File :: Temp является частью стандартной библиотеки:
use File::Temp;
my( $temp_fh, $tempfile ) = tempfile();
Теперь запишите все в $temp_fh
, пока не убедитесь, что вы смогли завершить вывод. После этого используйте rename
, чтобы переместить готовый файл на место:
rename $tempfile => $original;
Шон также правильно указывает, что это изменит индекс, тем самым нарушая жесткие ссылки. Вы можете скопировать новый файл в старый, если это имеет значение для вас, но я редко видел ситуацию, когда технология была настолько продвинутой:)
Если вы запутались, исходные данные все еще там, и вы можно попробовать еще раз. Примечание: это предполагает, что два файла находятся в одном разделе, поскольку это требование rename
.
. Хотя это может не иметь значения в вашем случае, вы также должны учитывать, что другие потребители делают в это время. берет вас, чтобы написать новый файл. Что произойдет, если другая программа захочет прочитать исходный файл сразу после того, как вы его урезали, но не записали данные (или написали не полностью)? Как правило, вы хотите убедиться, что файл завершен, прежде чем он станет доступен для других программ.
Если вам не нравится временный файл, есть другие способы решения проблемы. Переместите исходный файл на имя резервной копии, затем прочитайте его и запишите исходное имя. Или введите другое имя файла и переместите его на место. См., Например, Perl настройки -i
переключателя командной строки только для этой проблемы.