tags:

views:

114

answers:

4

Hi. Is it possible to have 2 file handles for the same file?

open TXT,"+>","New" or die "Cannot Create File \n";
print TXT "Line1 \n";
open TXT1, ">>New" or die "Cannot open file";
print TXT1 "Line2 \n";

will this work?

A: 

Yes, but why would you need to?

Andrew
+1  A: 

YES, it is possible to have more than one file handler for the same file. This will work.

    use strict;
    use warning;
    my $path = 'testfile';
    open TXT,"+>",$path or die "Cannot Create File \n";
    printf TXT "Line1\n";

    open TXT1, ">>",$path or die "Cannot open file";
    printf TXT1 "Line2\n" ;
    close TXT;
    close TXT1;
Nikhil Jain
+2  A: 

Yes, it will work. It is ok to have several handles to the same file.

But be careful that your first file is in overwrite mode. TXT1 will always write at end of file but TXT will remain at its previous location and overwrite whatever is there or not depending on buffering.

If you do:

print TXT "Line 1\n";
print TXT1 "Line 2\n";
print TXT "Line 3\n";
close TXT;
close TXT1;

You will have:

Line 1
Line 3
Line 2

but if you do:

print TXT "Line 1\n";
print TXT1 "Line 2\n";
close TXT1; # this writes the buffer to disk
print TXT "Line 3\n";
close TXT;

You will have:

Line 1
Line 3

Line 2 is written then overwritten by Line 3. While in the first case, Line 3 is in the buffer, Line 2 is written because the file is closed first and then Line 3 is written in append.

So, use with care !

Eric Darchis
+1  A: 

Yes, it's possible to open multiple handles to the same file, but (1) the outcome might not be what you want (see below), and (2) do you really need to do this or is there a better way to solve your larger problem?

That said, here's what a little experimentation revealed on my Windows machine:

Open one file in write mode, one file in append mode:

my $file_name = 'text_write_append.txt';
open(my $fh1, ">",  $file_name) or die $!;
open(my $fh2, ">>", $file_name) or die $!;

print $fh1 "foo\n" x 1;
print $fh2 "bar\n" x 2;
print $fh1 "x";

The second write to $fh1 picks up where its previous write left off, stomping over the first bar and truncating the second. Probably not what you want.

foo
xar

Open both files in append mode.

my $file_name = 'text_append_append.txt';
open(my $fh0, ">",  $file_name) or die $!; close $fh0; # Create empty file.
open(my $fh1, ">>", $file_name) or die $!;
open(my $fh2, ">>", $file_name) or die $!;

print $fh1 "foo\n" x 1;
print $fh2 "bar\n" x 2;
print $fh1 "x";

All of our output is present, but in the wrong order.

bar
bar
foo
x

Open both files in append mode, without buffered output.

my $file_name = 'text_append_append_flush.txt';
open(my $fh0, ">",  $file_name) or die $!; close $fh0;
open(my $fh1, ">>", $file_name) or die $!; select $fh1; $| = 1; # No buffering.
open(my $fh2, ">>", $file_name) or die $!; select $fh2; $| = 1;

print $fh1 "foo\n" x 1;
print $fh2 "bar\n" x 2;
print $fh1 "x";

Probably what you expect (but note that unbuffered writing is generally slower than buffered writing).

foo
bar
bar
x
FM