Neon Flash
Neon Flash

Reputation: 3233

Perl Read/Write File Handle - Unable to Overwrite

I have a Perl Script which performs a specific operation and based on the result, it should update a file.

Basic overview is:

  1. Read a value from the file handle, FILE
  2. Perform some operation and then compare the result with the value stored in INPUT file.
  3. If there is a change, then update the file corresponding to File Handle.

When I say, update, I mean, overwrite the existing value in INPUT file with the new one.

An overview of the script:

#! /usr/bin/perl

use warnings;
use diagnostics;

$input=$ARGV[0];
open(FILE,"+<",$input) || die("Couldn't open the file, $input with error: $!\n");

# perform some operation and set $new_value here.

while(<FILE>)
{
chomp $_;
$old_value=$_;
if($new_value!=$old_value)
{
 print FILE $new_value,"\n";
}
}

close FILE;

However, this appends the $new_value to the file instead of overwriting it.

I have read the documentation in several places for this mode of FILE Handle and everywhere it says, read/write mode without append.

I am not sure, why it is unable to overwrite. One reason I could think of is, since I am reading from the handle in the while loop and trying to overwrite it at the same time, it might not work.

Thanks.

Upvotes: 1

Views: 4875

Answers (3)

shawnhcorey
shawnhcorey

Reputation: 3601

You should add truncate to your program along with seek.

if( $new_value != $old_value )
{
    seek( FILE, 0, 0 );
    truncate FILE, 0;
    print FILE $new_value,"\n";
}

Since the file is opened for reading and writing, writing a shorter $new_value will leave some of the $old_value in the file. truncate will remove it.

See perldoc -f seek and perldoc -f truncate for details.

Upvotes: 1

mask8
mask8

Reputation: 3638

your guess is right. You first read the file so file pointer is actually in the position of end of old value. I didn't try this myself, but you can probably seek file pointer to 0 before print it out.

seek(FILE, 0, 0);

Upvotes: 4

John Corbett
John Corbett

Reputation: 1615

you have to close the file handle and open a different one (or the same one if you like) set to the output file. like this.

close FILE;
open FILE, ">$input" or die $!;

...

close FILE;

that should do the trick

Upvotes: 0

Related Questions