GeNeTiCstdent
GeNeTiCstdent

Reputation: 1

Error with opening a filehandle

I have just begun working with Perl, I am only at the introductory level, and I have been having trouble with opening filehandles.

Here is the code:

#!/usr/bin/perl -w

$proteinfilename = 'peptide';

open(PROTEINFILE, $proteinfilename) or die "Can't write to file '$proteinfilename' [$!]\n";

$protein = <PROTEINFILE>;

close PROTEINFILE;

print $protein;

exit;

Every time I tried to run the program, it gave me an error

readline() on closed filehandle PROTEINFILE at C:\BIN\protein.pl

or

Can't write to file 'peptide' [No such file or directory]

Can you please help me figure this out. I have the file peptide saved as a .txt and its in the same folder as the protein.pl. What else can I do to make this work?

Upvotes: 0

Views: 3370

Answers (3)

user966588
user966588

Reputation:

Here how your program will go

#!/usr/bin/perl
use strict;
use warnings;

my $proteinfilename = 'peptide.txt';

open(PROTEINFILE, $proteinfilename) or die "Can't write to file '$proteinfilename' [$!]\n";

my $protein = <PROTEINFILE>;

close PROTEINFILE;

print $protein;

You need to add the file extension(for example .txt) at the end like below.

my $proteinfilename = 'peptide.txt';

Your program say peptide_test.pl and input text file peptide.txt should be in the same directory.
If they are not in the same directory, use absolute path like below.

my $proteinfilename = 'C:\somedirectory\peptide.txt';

Note: Use single quotes in case of absolute path.This will ignore the backslash\ in path.

Now about errors, If you don't use die statement, you will get error

readline<> on closed filehandle PROTEINFILE at C:\BIN\protein.pl

After using die,

or die $! ;

you will get error No such file or directory.

Also always

use strict;  
use warnings;

-w is deprecated after perl 5.6. These two lines/statements will help you finding typos,syntax errors

And one more,I don't think you need exit;, at the end. Refer exit function.

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753455

Are you looking to open the file for reading or writing? Your open statement opens it for reading; your error message says 'writing'. You use it for reading — so your error message is confusing, I believe.

If you get 'No such file or directory' errors, it means that despite what you thought, the name 'peptide' is not the name of a file in the current directory. Perl does not add extensions to file names for you; if your file is actually peptide.txt (since you mention that it is a 'txt file'), then that's what you need to specify to open. If you run perl protein.pl and peptide (or peptide.txt) is in the current directory, then it is not clear what your problem is. If your script is in C:\BIN directory and your current directory is not C:\BIN but peptide (or peptide.txt) is also in C:\BIN, then you need to arrange to open C:/bin/peptide or c:/bin/peptide.txt. Note the switch from backslashes to slashes. Backslashes have meanings specific to Perl as an escape character, and Windows is happy with slashes in place of backslashes. If you must use backslashes, then use single quotes around the name:

my $proteinfilename = 'C:\BIN\peptide.txt';

It may be simplest to take the protein file name from a command line argument; this gives you the flexibility of having the script anywhere on your PATH and the file anywhere you choose.


Two suggestions to help your Perl:

  1. Use the 3-argument form of open and lexical file handles, as in:

    open my $PROTEINFILE, '<', $proteinfilename or
        die "Can't open file '$proteinfilename' for reading [$!]\n";
    
    my $protein = <$PROTEINFILE>;
    
    close $PROTEINFILE;
    

    Note that this reads a single line from the file. If you need to slurp the whole file into $protein, then you have to do a little more work. There are modules to handle slurping for you, but you can also simply use:

    my $protein;
    { local $/; $protein = <$PROTEINFILE>; }
    

    This sets the line delimiter to undef which means the entire file is slurped in one read operation. The $/ variable is global, but this adjusts its value in a minimal scope. Note that $protein was declared outside the block containing the slurp operation!

  2. Use use strict; as well as -w or use warnings;. It will save you grief over time.

I've only been using Perl for 20 years; I don't write a serious script without both use strict; and use warnings; because I don't trust my ability to spot silly mistakes (and Perl will do it for me). I don't make all that many mistakes, but Perl has saved me on many occasions because I use them.

Upvotes: 1

ikegami
ikegami

Reputation: 385506

You're telling perl to open file peptide in the current directory, but it doesn't find such a file there ("No such file or directory").

Perhaps the current directory isn't C:\BIN, the directory in which you claim the file is located. You can address that by moving the file, using an absolute path, or changing the current directory to be the one where teh script is located.

use Cwd        qw( realpath );
use Path::File qw( file );

chdir(file(realpath($0))->dir);

Perhaps the file isn't named peptide. It might actually be named peptide.txt, for example. Windows hides extensions it recognises by default, a feature I HATE. You can address this by renaming the file or by using the correct file name.

Upvotes: 4

Related Questions