Ошибка при открытии файлового дескриптора - PullRequest
0 голосов
/ 05 марта 2012

Я только начал работать с Perl, я только на начальном уровне, и у меня были проблемы с открытием файловых дескрипторов.

Вот код:

#!/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;

КаждыйКогда я пытался запустить программу, она выдала мне ошибку

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

или

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

Можете ли вы помочь мне разобраться с этим.У меня есть файл пептид, сохраненный как .txt, и он находится в той же папке, что и protein.pl .Что еще я могу сделать, чтобы сделать эту работу?

Ответы [ 3 ]

4 голосов
/ 05 марта 2012

Вы говорите perl, чтобы открыть файл peptide в текущем каталоге, но такого файла там нет («Нет такого файла или каталога»).

Возможно, текущийкаталог не C:\BIN, каталог, в котором вы утверждаете, что файл находится.Вы можете решить эту проблему, переместив файл, используя абсолютный путь или изменив текущий каталог на каталог, в котором находится скрипт.

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

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

Возможно, файл не имеет названия peptide.Например, он может быть назван peptide.txt.Windows скрывает расширения, которые она распознает по умолчанию, функция, которую я ненавижу.Вы можете решить эту проблему, переименовав файл или используя правильное имя файла.

1 голос
/ 05 марта 2012

Вот как пойдет ваша программа

#!/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;

Вам необходимо добавить расширение файла (например, .txt) в конце, как показано ниже.

my $proteinfilename = 'peptide.txt';

Ваша программа скажет peptide_test.pl, и входной текстовый файл peptide.txt должен находиться в одном каталоге.
Если они не находятся в одном каталоге, используйте абсолютный путь, как показано ниже.

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

Примечание: используйте одинарные кавычки в случае абсолютного пути. Это игнорирует обратную косую черту \ в пути.

Теперь об ошибках. Если вы не используете оператор die, вы будетеполучить ошибку

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

После использования die

or die $! ;

вы получите ошибку No such file or directory.

Также всегда

use strict;  
use warnings;

-w устарела после perl 5.6.Эти две строки / утверждения помогут вам найти опечаток, синтаксических ошибок

И еще, я не думаю, что вам нужно exit;, в конце. См. Функцию выхода.

1 голос
/ 05 марта 2012

Вы хотите открыть файл для чтения или записи? Ваше заявление open открывает его для чтения; ваше сообщение об ошибке говорит «запись». Вы используете его для чтения & mdash; так что ваше сообщение об ошибке сбивает с толку, я полагаю.

Если вы получаете ошибки «Нет такого файла или каталога», это означает, что, несмотря на то, что вы подумали, имя «пептид» не является именем файла в текущем каталоге. Perl не добавляет расширения к именам файлов для вас; если ваш файл на самом деле peptide.txt (поскольку вы упоминаете, что это «текстовый файл»), то это то, что вам нужно указать для open. Если вы запустите perl protein.pl и peptide (или peptide.txt) в текущем каталоге, тогда неясно, в чем ваша проблема. Если ваш сценарий находится в каталоге C:\BIN, а текущий каталог не C:\BIN, но peptide (или peptide.txt) также находится в C:\BIN, то вам необходимо организовать открытие C:/bin/peptide или c:/bin/peptide.txt. Обратите внимание на переключение с обратной косой черты на косую. Обратная косая черта имеет значения, характерные для Perl как escape-символа, и Windows довольна косой чертой вместо обратной косой черты. Если вы должны использовать обратную косую черту, то используйте одинарные кавычки вокруг имени:

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

Проще всего взять имя файла белка из аргумента командной строки; это дает вам возможность иметь скрипт в любом месте вашего PATH и файл в любом месте по вашему выбору.


Два предложения, которые помогут вашему Perl:

  1. Используйте форму с тремя аргументами open и лексические дескрипторы файлов, как в:

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

    Обратите внимание, что это читает одну строку из файла. Если вам нужно записать весь файл в $protein, вам придется проделать еще немного работы. Для вас есть модули, которые справляются с хлебопечением, но вы также можете просто использовать:

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

    Устанавливает разделитель строки на undef, что означает, что весь файл удаляется за одну операцию чтения. Переменная $/ является глобальной, но это корректирует ее значение в минимальной области видимости. Обратите внимание, что $protein было объявлено вне блока, содержащего операцию slurp!

  2. Используйте use strict;, а также -w или use warnings;. Это спасет вас от скорби.

Я использую Perl только 20 лет; Я не пишу серьезный сценарий без use strict; и use warnings;, потому что не доверяю своей способности выявлять глупые ошибки (и Perl сделает это за меня). Я не делаю столько ошибок, но Perl много раз спасал меня, потому что я их использую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...