Nikhil
Nikhil

Reputation: 586

Read and Write Operation in perl script

I am Newbie to Perl script.

I want to do a read and write operation on a file. I will open a file in read and write mode (+<), and will write into a file. Now, I want read the file whatever I have written to it previously. Below is my code:

#!/usr/bin/perl

`touch file.txt`; #Create a file as opening the file in +< mode
open (OUTFILE, "+<file.txt") or die "Can't open file : $!";

print OUTFILE "Hello, welcome to File handling operations in perl\n"; #write into the file

$line = <OUTFILE>; #read from the file

print "$line\n"; #display the read contents.

When I am displaying the read contents it's showing a blank line. But the file "file.txt" has the data

Hello, welcome to File handling operations in perl

Why am I not able to read the contents. Whether my code is wrong or am I missing something.

Upvotes: 2

Views: 2572

Answers (2)

Joel Berger
Joel Berger

Reputation: 20280

The problem is that your filehandle position is located after the line you have written. Use the seek function to move the "cursor" back to the top before reading again.

An example, with some extra comments:

#!/usr/bin/env perl

# use some recommended safeguards
use strict;
use warnings;

my $filename = 'file.txt';
`touch $filename`;

# use indirect filehandle, and 3 argument form of open
open (my $handle, "+<", $filename) or die "Can't open file $filename : $!";
# btw good job on checking open sucess!

print $handle "Hello, welcome to File handling operations in perl\n";

# seek back to the top of the file
seek $handle, 0, 0;

my $line = <$handle>;

print "$line\n";

If you will be doing lots of reading and writing you may want to try (and not everyone suggests it) using Tie::File which lets you treat a file like an array; line access by line number (newline written automatically).

#!/usr/bin/env perl

# use some recommended safeguards
use strict;
use warnings;

use Tie::File;

my $filename = 'file.txt';
tie my @file, 'Tie::File', $filename
  or die "Can't open/tie file $filename : $!";

# note file not emptied if it already exists

push @file, "Hello, welcome to File handling operations in perl";
push @file, "Some more stuff";

print "$file[0]\n";

Upvotes: 5

TLP
TLP

Reputation: 67900

This is a seemingly common beginner mistake. Most often you will find that reading and writing to the same file, while possible, is not worth the trouble. As Joel Berger says, you can seek to the beginning of the file. You can also simply re-open the file. Seeking is not as straightforward as reading line by line, and will present you with difficulties.

Also, you should note, that creating an empty file beforehand is not required. Simply do:

open my $fh, ">", "file.txt" or die $!;
print $fh "Hello\n";
open $fh, "<", "file.txt" or die $!;
print <$fh>;

Note that:

  • using open on the same file handle will automatically close it.
  • I use three-argument open, and a lexical (defined by my) file handle, which is the recommended way.
  • you do not need to add newline when printing a variable read in line by line mode, as it will already have a newline at the end. Or end of file.
  • You can use print <$fh>, as the print statement is in list context, it will extract all the lines from the file handle (print the entire file).

If you only want to print one line, you can do:

print scalar <$fh>;  # put <$fh> in scalar context

Upvotes: 0

Related Questions