Почему я не могу открыть файлы, возвращенные Perl readdir?

Ну, я знаю, что это еще один вопрос новичка, но я очень расстроен и надеюсь снова стать просветленным. Под руководством вас, ребята, я уже научился использовать функцию glob для чтения содержимого каждого файла в каталоге. Сейчас я пытаюсь использовать комбинацию readdir-foreach, чтобы сделать то же самое, но продолжаю получать сообщение об ошибке «Не удается открыть файл. Отказано в доступе». Почему это происходит с тем же каталогом, теми же файлами и мной, что и администратор. Может кто-то любезно показать мне, что я делаю не так? Спасибо.

Следующий код использует функцию glob, и она работает:

#! perl
my $dir = 'f:/corpus/';
my @files = glob "$dir/*";
foreach my $file (@files) {
open   my $data, '<',"$file" or die "Cannot open FILE";
while(<$data>) {
...}

Следующий код завершается ошибкой, и в сообщении об ошибке говорится: «Не удается открыть FILE: разрешение отклонено». Но почему?

#! perl
my $dir = 'f:/corpus/';
opendir (DIR,'f:/corpus/') or die "Cannot open directory:$!";
my @files=readdir(DIR);
closedir DIR;
foreach my $file (@files) {
open   my $data, '<',"$file" or die "Cannot open FILE:$!";
while(<$data>) {
...}
13.10.2009 02:30:15
В ваших заметках о смерти вы должны включить имя файла ($ file), а не просто указать FILE. И вы должны использовать переменную $ dir в вызове opendir () - и использовать ее в заметке о смерти.
Jonathan Leffler 13.10.2009 02:48:23
Да, с $ file в моих заметках о смерти сообщение об ошибке кажется более конкретным. Запуск исходный код дает мне «Не удается открыть: Отказано в Предполагаю , что это произошло потому , что фильтр , который bobbymcr предложил не применялся Спасибо за напоминание...!
Mike 13.10.2009 03:55:17
2 ОТВЕТА
РЕШЕНИЕ

readdir()Функция возвращает только имя файла, а не полный путь. Таким образом, вы пытаетесь открыть, например, "foo.txt"вместо "f: \ corpus \ foo.txt".

8
13.10.2009 02:34:22
Просто чтобы добавить возможное решение:use File::Spec; open my $data, '<', File::Spec->catfile($dir, $file);
ephemient 13.10.2009 02:39:00
Еще лучше использовать что-то вроде File :: Next или Path :: Class.
jrockway 13.10.2009 02:43:58
Спасибо Энди за разъяснения! Это имеет смысл. и спасибо, эфемиент и джоквей. Я сейчас пытаюсь исправить File :: Next.
Mike 13.10.2009 03:05:19
Я попробовал исправить эфемиент в сочетании с фильтром bobbymcr, и он отлично работал :)
Mike 13.10.2009 03:37:09
Были проблемы с использованием File: Next исправить, хотя. Perl дал мне сообщение об ошибке, говорящее что-то вроде «Не удается найти файл / next.pl». Думаю, это потому, что модуль File :: Next не был установлен.
Mike 13.10.2009 03:42:45

Вы должны иметь в виду , что readdirимена каталогов возвращает и имена файлов. Скорее всего, вы пытаетесь открыть одну из специальных записей каталога .или ..которые вам обычно нужно отфильтровать, если вы используете эти функции:

foreach my $f (@files)
{
    # skip special directory entries
    if ($f ne '.' && $f ne '..')
    {
        # ...
        print "$f\n";
    }
}

Также обратите внимание на предложение Энди Росса , что это вернет только относительный путь, а не полный путь.

4
23.05.2017 10:09:38
Спасибо bobbymcr. Я добавил условное выражение if ($ f ne '.' && $ f ne '..'), но все равно получаю сообщение об ошибке, но что-то не так. Он говорит: «Невозможно открыть файл: нет такого файла или каталога». Таким образом, проблема, вероятно, заключается в том, что предложил Энди Росс: readdir возвращает только относительный путь, а не полный путь. Но спасибо же!
Mike 13.10.2009 03:02:00
Я думаю, что у вашего кода были и проблемы, и комбинация этих двух факторов дала вам нужный вам ответ. «Отказано в доступе» - это определенно ошибка, возникающая при попытке открыть каталог с помощью open (). Попробуйте open(FILE, "<.") or die "Cannot open FILE:$!";и увидите это в действии ...
bobbymcr 13.10.2009 03:14:08
Ах, bobbymcr, вы, вероятно, правы. Без фильтра, который вы предложили, у меня есть предупреждение, которое выглядит примерно так: readline () для закрытого дескриптора файла. Спасибо :)
Mike 13.10.2009 03:35:15