http://www.perlmonks.org?node_id=960

File input and output is not much of a stretch from normal I/O. Basically you have to use the open command to open a filestream and then read to and write from it. Then once you're done with it you use close to close the file. The syntax for opening a file is:

open(FILEHANDLE,"filename");

This opens a new filehandle with the name of FILEHANDLE, and associates it with filename which is the location of the file on your disk. This works for reading a file. If you want to write to it you need to put a > in front of the filename as seen below:

open(FILEHANDLE,">filename");

To append to a file you use >> in front of the filename as you can see here:

open(FILEHANDLE,">>filename");

Now for some quick examples:
open(FILE, "data.txt"); #opens data.txt in read-mode while(<FILE>){ #reads line by line from FILE which i +s the filehandle for data.txt chomp; print "Saw $_ in data.txt\n"; #shows you what we have read } close FILE; #close the file.

To print stuff to a file you merely through a line into your program like:

print FILEHANDLE "your text here\n";

FILEHANDLE needs to be a FILEHANDLE you currently have open. Notice there is no comma between the FILEHANDLE and the stuff your printing out. That is the way it needs to be. Now for a more extended example:
open FILE, ">keylogger.dat"; #opens file to be written to while(<>){ #while we're getting input from the keyb +oard print FILE $_; #write it to our file } close FILE; #then close our file.


Another thing you might want to look into are the filetest operators these allow you to do things like test whether a file exists, is readable, is writable among other things. complete information look at the documentation

Replies are listed 'Best First'.
RE: File Input and Output
by LeGo (Chaplain) on Aug 02, 2000 at 18:02 UTC
    I wanted to add a bit that I have learned to help you when you start to program and have errors.

    It is always good to make sure the file you are opening opens. Because if it doesn't the program will just keep running with no errors and you will not get your desired results. The easiest way to do this is.

    open (FILE, "file") || die "file could not be opened";
    Then as you program more you will probably do something more like this in all of your programs.

    $file = "some_file.txt"; open(FILE,"$file") or &Error($!);
    And then at the end of your code where you put your subs put this.

    sub Error { $error = shift or $error = "unknown"; print "Sorry, but there was an error. Could not open $file"; print "Error: $error"; &End; }
    Another thing that is good to do is to make sure that your close is successful.
    close FILE or die "Could not close $file";
    And as before you can write special subroutines to help specify your error for closing. This is very helpful when writing CGI scripts and making them look good when they do not open or close files.

    LeGo

RE: File Input and Output
by SYbeginner (Novice) on Jun 17, 2000 at 07:48 UTC
    Also if a file doesn't exisit the following code will generate the file on the server although I can't figure out why:
    open(file, ">$filename") flock file, 2; print file "Whatever you want to say"; close(file);
    And after that it generates a file on the server, could someone explain it for me?
      It doesn't do much good to flock a file that you've already erased. Perhaps you are mixing things from different stuff you've seen in some sort of "opcode soup" that you hope will taste good once you're done.

      To me, it's bad from the first taste. :)

      -- Randal L. Schwartz, Perl hacker

      of course it will create a new file. since you have opened it in write mode..it will open a new file and write data into it. if the file had already existed it would have removed the whole existing data and just put in data you just wrote. to prevent this open in >> mode
        It occurs to me that this fact might not be intuitively obvious to someone that isn't already used to that behavior, as for instance from regular use of bash. It's intuitively obvious to me, but I'm a penguinista. Those who write Perl but use Windows, for instance, wouldn't be used to that kind of behavior. Remember that in the Windows GUI environment files never get named until they're saved after editing. Habitual Windows users probably never realize that what's going on is that the file is actually only being "opened" for the first time when that "okay" button in the save dialog is clicked.

        So: For those of us used to that sort of behavior (like 'nix users), it's "Of course it will create a new file." For those who are not (like Windows users), it's "Oh. That's news to me."

        The fact that one must use >> instead of > to edit an already extant file without wiping out its contents is an important fact, though, and it's a good thing you brought it up. It should really be included in the text of the tutorial itself.

        - apotheon

        CopyWrite Chad Perrin
RE: File Input and Output
by Anonymous Monk on May 03, 2000 at 04:57 UTC
    running this code: open(FILE, "data.txt"); #opens data.txt in read-mode while(<FILE>){ #reads line by line from FILE which is the filehandle for data.txt chomp; print "Saw $_ in data.txt\n"; #shows you what we have read } close FILE; #close the file. results in: # perl test1 syntax error at test1 line 5, near "<" syntax error at test1 line 5, near ">" Execution of test1 aborted due to compilation errors.
      root just forgot that you don't need to escape less-than and greater-than signs inside <CODE> tags. Obviously, it should read:
      while(<FILE>)
        So, in summary, here's how you deal with open():

        #!/usr/bin/perl print"Gimmie a filename to examine: "; $filename=<STDIN>; open(FILE,$filename); while(<FILE>) { chomp; print "Found $_ in $filename" } close FILEDESC;
RE: File Input and Output
by SYbeginner (Novice) on Jun 17, 2000 at 07:49 UTC
    Also if a file doesn't exisit the following code will generate the file on the server although I can't figure out why:
    open(file, ">$filename") flock file, 2; print file "Whatever you want to say"; close(file);
    And after that it generates a file on the server, could someone explain it for me?
Re: File Input and Output
by gpoduval (Initiate) on Jan 30, 2001 at 11:42 UTC
    hmm...when i tried the >>filename nothing got appended into the file. it remained as it is
    i am using activestate activeperl for windows on win2k.

    i suspect this might be because i dont know how to end a program. anybody can help me ? www.comp.nus.edu.sg/~gokulpod
      No, before you can help yourself. Try Linux or FreeBSD or OpenBSD instead of Redmond crap. Now serious. try:

      #!/usr/bin/perl

      open(OUTPUT,">>/tmp/file");

      $a = "some text...";

      print OUTPUT $a;


      Now, change the /tmp/file and stuff to anything you want to.
      HTH

      vfs ("The Perl Monkey") :)

        I forgot this:

        it 's better to assign a variable to a filename, as:

        $b = "/tmp/file";

        Then change the filename in open to the name of that variable.

        Cheers.

        vfs.

        Im having the same problem w/ writing to a file, using Win2k/ActivePerl Thinking that win2k is not handling the opening of files correctly. Please, without saying, dont use win2k, can someone post a work around? I updated w/ the suggestion you posted as such:
        #!perl -w open(FILE, "data.txt"); #opens data.txt in read-mode while(<FILE>){ #reads line by line from FILE which i +s the filehandle for data.txt chomp; print "Saw $_ in data.txt\n"; #shows you what we have read } close FILE; #close the file. $a = "keylogger.dat"; open FILE, ">$a" or die; #opens file to be written to while(<>){ #while we're getting input from the keyb +oard print FILE $_; #write it to our file } close FILE; #then close our file.
        "Re: File Input and Output by gpoduval on Jan 30, 2001 at 06:42 hmm...when i tried the >>filename nothing got appended into the file. it remained as it is i am using activestate activeperl for windows on win2k. i suspect this might be because i dont know how to end a program. anybody can help me ? www.comp.nus.edu.sg/~gokulpod"
      I believe you need work in a directory like that, c:\test. It happened to me same you, because I´ve worked in a directory like this x:\test. Luiyi, luiyi2manu@gmail.com
Re: File Input and Output
by Anonymous Monk on Jun 08, 2001 at 18:54 UTC
    is there some way to read in an input & store it character by character?
      getc. Note well the documentation -- it's still buffered input!

      ObSampleCode:

      while ($_ = getc STDIN) { $_ = ord $_; printf "%02x %c\n", $_, 32 <= $_ && $_ < 127 ? $_ : ord '?'; }
Re: File Input and Output
by gariki (Initiate) on Jul 11, 2001 at 22:26 UTC
    need small help, when i am trying to read from the file and write to the file it is working perfect, but when i am trying to read from the key board and write to the file the file is not being written. There are no problems with opening files i guess. can u help.. sorry for asking such trivial question. and if u know of any message board for perl please let me know so that i may post my questions there in future.. n here is my code... _______________
    #!/usr/bin/perl -w #open(IN, "input.txt"); open(OUT, ">out.txt"); while( <STDIN>) { print $_; print OUT $_; } #close (IN); close (OUT);
    ______________________ thanks Gariki.
      try this. #!/usr/bin/perl -w use strict; my $output_file = "out.txt"; my $user_input = ""; my $quit_code = "quit\n"; open(OUTPUT, ">$output_file) || die "Unable to open $output_file for writing: $!\n"; while ($user_input ne $quit_code) { print "Enter some text: "; $user_input = <STDIN>; print OUTPUT $user_input; } close(OUTPUT) || die "Unable to close $output_file: $!\n;
Re: File Input and Output
by Anonymous Monk on Dec 25, 2001 at 05:18 UTC
    This is what was on the web page for the first example: while(&ltFILE&gt){ #reads line by line from FILE w +hich is the filehandle for data.txt
      Hi, I have just started working on PERL and am facing this problem. Is the implementation done like this? i have a text file sample.txt which has 3 lines abc deg hij when i read everything once i get all the details and then am not able 2 read it again. code used is open(file1,"sample.txt"); print(<file1>); $line1=<file>; print($line1); This does not print anything. Can u pls suggest?Have I done some mistake? Thanks KP
What is the error in my script or file setup?
by Anonymous Monk on Jul 24, 2001 at 14:12 UTC
    How come this never displays "Yes!" ? input.dat:
    fred 20.4 harv 5.6 tony 5.13 dennis 401.1
    My code:
    open(FILE, "input.dat"); @list; while(<FILE>) { chomp; push @list, $_; } $i="harv"; $loc=-1; $cnt=0; foreach $list(@list) { if($i eq $list) { print "YES!\n"; } }

    Edit kudra, 2001-07-25 Changed title

      mmhhh, different possibilites that this doesn't work

      • try if this works:
        use strict; use warnings; my @list; while(<DATA>) { chomp; push @list, $_; } my $i="harv"; foreach my $list (@list) { if($i eq $list) { print "YES!\n"; } } __DATA__ fred 20.4 harv 5.6 tony 5.13 dennis 401.1
        The DATA section behaves exactly like a file - inside your file and you don't have to open it. If it does then
      • check if your file opened correctly (and specify the opening mode): open (FILE, "<", "input.dat") or die "Couldn't open input.dat: $!"; The die will abort the program if 'input.dat' couldn't be opened. The $! variable contains an error message and is set automatically if an error during the open occured.
      • You should use strict; and use warnings; (equivalent to perl -w). It protects you from typing mistakes - there aren't any in your example, this is more general advice. And it shows useful warnings if you do some possibly 'stupid' things.

      -- Hofmator

      I recently had a similar problem. The error is in your comparison ($i eq $list). Then the loop gets to the point that you are expecting a "Yes", the values of your variables are $i="harv" $list="harv\n" I solved my problem by changing $i to include the carriage return. You could also solve this problem by using pattern matching rather than a straight comparison, or by chopping off the last character of the input lines.
        It looked like he was chomping in his code. He was chomping the list as he added each element to the array. That should take care of the carriage return that you are referring to.

      Trailing space after "harv" in your input file? Or perhaps a carriage return and you are on Unix?

              - tye (but my friends call me "Tye")

      This works:

      @list = qw( fred 20.4 harv 5.6 tony 5.13 dennis 401.1 ); $i="harv"; foreach $list(@list) { if($i eq $list) { print "YES!\n"; } }

      Suggest you add open (FILE, "input.dat") or die "Oops can't open input.dat Perl says $!\n"; which will *probably* tell you that perl cna't find your file. Also you don't need to push your data into an array as you do but that is by the by.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: File Input and Output
by barun (Novice) on Feb 07, 2005 at 15:38 UTC
    i am running this code to create a new file.But i am simply getting a blank file after runing this code .I am using Ctrl+Z to terminate writing.I hope i m missing something .Can anyone point out my mistake ?
    open FILE, ">keylogger.dat";
    while(<>){
    print FILE $_;
    }
    close FILE;
      itś working with ctrl+d
Re: File Input and Output
by grashoper (Monk) on Aug 23, 2007 at 16:40 UTC
    Ah good stuff here, I have succesfully opened my file and echoed its output, now I want to figure how to read in a number of files, and replace a value within each file, these files are in multiple directories..with differing account codes as names, the files themselves are named with the current date.txt I need to read in about 80 directories, parsing each file for current date, and modify the files to remove this "bad" value then re-write to original filename..

      I m having trouble using this in a script. I have a test file that looks like :

      open(my $fh1, ">>", "outputcontrol.txt"); open(my $fh2, ">>", "outputoutput.txt"); while ( <> ) { my $count = ($_ =~ y/x//); print "$count \n"; # print $_; if ( $count != $delim_amnt_per_line ) { print fh1 $_; } my ($prefix) = substr $_, 0, 7; next if $seen{$prefix}++; print fh2 $_; }

      Its supposed to do some checks on delimiter per line and remove duplicates based on a substring, my problem is that i have zero output on the filehandles. Whereas if i ran it with just print it would print normally, both expected outputs on STDOUT. Can someone help me?

        You replied to a node from 2007, its author was last here 1 year ago.

        Nevertheless, when using lexical filehandles (i.e. open my $fh1, the dollar sign isn't optional. Fix:

        print $fh2 $_; # ^ # | # Here.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: File Input and Output
by chai2007 (Initiate) on May 07, 2007 at 15:23 UTC
    Hi , I am writing a program were I read the input files containing the ID and date_modified. Now I want to create reports(i.e a set of files) for each date. Please suggest me how I can create the files with different names as dates Thanks in advance