Forum Webscript.Ru

Программирование => Perl => Тема начата: Отец Никон от 05 Февраля 2003, 22:21:05

Название: Чтение файлов из дир-ии и пр.
Отправлено: Отец Никон от 05 Февраля 2003, 22:21:05
1) Можно ли из папки прочитать только х+у файлов, где х-начальная позиция, а у-последняя? (Надо отобразить список тем форума.)
2) Как отсортировать массив этих прочитанных фалов по дате, алфавиту и пр.?
Название: Чтение файлов из дир-ии и пр.
Отправлено: NeoNox от 05 Февраля 2003, 22:41:49
perldoc -f readdir
perldoc -f sort
Название: Чтение файлов из дир-ии и пр.
Отправлено: Chs от 06 Февраля 2003, 11:31:14
+ perldoc -f stat :)
Название: Чтение файлов из дир-ии и пр.
Отправлено: Отец Никон от 07 Февраля 2003, 19:09:21
Это не ответы: все функции, которые вы назвали, мне известны.

Во-первых: readdir читает все фалы из директории. Мне этого не надо.
Во-вторых о sort. Как сделать сортировку по дате? Надо ли записать так: $a=stat, $b=stat и затем sort или как-то иначе.
Название: Чтение файлов из дир-ии и пр.
Отправлено: NeoNox от 07 Февраля 2003, 19:33:14
Цитировать
Это не ответы:

Не функции должны быть известны, а что они делают должно быть известным.
Цитировать
Во-первых: readdir читает все фалы из директории.

Искуственный интеллект у этой функции отсутствует. Выбирай в массив и далее уже по индексам бери столько сколько нужно.
Цитировать
Во-вторых о sort. Как сделать сортировку по дате?

perldoc -f stat
получаешь из того же массива дату.
perldoc -f stat
Цитировать

Examples:

                   # sort lexically
                   @articles = sort @files;

                   # same thing, but with explicit sort routine
                   @articles = sort {$a cmp $b} @files;

                   # now case‐insensitively
                   @articles = sort {uc($a) cmp uc($b)} @files;

                   # same thing in reversed order
                   @articles = sort {$b cmp $a} @files;

                   # sort numerically ascending
                   @articles = sort {$a <=> $b} @files;
                 
                   # sort numerically descending
                   @articles = sort {$b <=> $a} @files;

Переводить комментарии надеюсь не нужно?
Кстати, в данном случае  я бы хэш использовал filename=>date.
Название: Чтение файлов из дир-ии и пр.
Отправлено: Отец Никон от 07 Февраля 2003, 19:54:53
Мне известно, естественно, что эти функции делают.
То, что из массива брать нужные индексы - это я допёр. Но, понимаешь, чем больше в папке файлов, тем дольше работает функция. Но, кажется, я нашёл решение...

По поводу sort - то, что ты процитировал - это, кажется, из справки по ПЕРЛу? Я только сегодня это читал.
Но, к сожалению, я опять не понял, как их по дате отсортировать... Можно пример?
Название: Чтение файлов из дир-ии и пр.
Отправлено: NeoNox от 07 Февраля 2003, 20:06:34
@not_sorted = (2, 1, 67, 23, 15, 10);
@sorted = sort {$a <=> $b} @not_sorted;
print join "\\n", @sorted;
Смысл понятен?
Название: Чтение файлов из дир-ии и пр.
Отправлено: Отец Никон от 07 Февраля 2003, 22:52:51
Да, конечно. Смысл этого понятен. Но не это надо...
Я сам виноват, что не сформулировал чётко вопрос.
На экран выводятся темы сообщений форума. Названия тем и дата их последнего изменения содержатся в файлах. Вот как я это делаю (вообще-то, это не я, а из книги Р. Колбурна, но я много добавил в его код...):  
Цитировать

@topics = grep (/^.+\\.txt$/, readdir (TOPICS));
...
&parse_topic;
...
print "$page_title\\n";
...
Здесь $page_title - заголовок темы.


Теперь процедура расшифровки файла.

Цитировать
sub parse_topic {
$topic_file = "$forums_path/$forum/" . $topic . ".txt";
eval {
open (TOPIC, "< $topic_file")
or die "Can\'t open $topic_file";
@topic_text = ;
};
$topic_text = join \'\', @topic_text;
# Extract the topic title from the topic
if ($topic_text =~ /(.*)<\\/title>/s) {<br />$page_title = $1;<br />}<br />else {<br />$err = "title";<br />return undef;<br />}<br /><br /># Extract the author from the topic<br />if ($topic_text =~ /<author>(.*)<\\/author>/s) {<br />$topic_author = $1;<br />}<br />else {<br />$err = "author";<br />return undef;<br />}<br /><br /># Extract the date when the file was last modified<br />if ($topic_text =~ /<last_modified>(.*)<\\/last_modified>/s) {<br />$last_modified = $1;<br />}<br />else {<br />$err = "lastmod";<br />return undef;<br />}</blockquote><div class="quotefooter"><div class="botslice_quote"></div></div><br /><br />Ты видишь, NeoNox, что и дата изменения и заголовок темы извлекаются из одного файла, и, замечу, не пишутся в массив, а всё время представлены одними и теми же переменными. Значит, чтобы отсортировать по алфавиту, дате и тп. надо соответственно отсортировать массив @topics. Понимаешь теперь? </dd> <dt class="postheader"> Название: <strong>Чтение файлов из дир-ии и пр.</strong><br /> Отправлено: <strong>Wyclef</strong> от <strong>08 Февраля 2003, 01:41:14</strong> </dt> <dd class="postbody"> <div class="quoteheader"><div class="topslice_quote">Цитировать</div></div><blockquote class="bbc_standard_quote"><br />отсортировать массив @topics.<br /></blockquote><div class="quotefooter"><div class="botslice_quote"></div></div><br /><br />Enjoy!<br /><br /><div class="quoteheader"><div class="topslice_quote">Цитировать</div></div><blockquote class="bbc_standard_quote"><br /># $field - по какому параметру сортировать<br /># @topics - не отсортированные топики >> @sorted<br /># <=> или cmp - в зависимости от типа<br /><br />my $field  = "last_modified";<br />my @sorted = sort { get_field($b, $field) <=> get_field($a, $field) } @topics;<br /><br />sub get_field {<br />my ($topic, $field) = @_;<br />my $topic_file = "$forums_path/$forum/" . $topic . ".txt";<br /><br />open (TOPIC, $topic_file) or die "Can\'t open $topic_file";<br />$/ = undef;<br />my $topic_text = <TOPIC>;<br /><br />my $res = $topic_text =~ /<$field>(.*)<\\/$field>/s ? $1 : undef;<br />return $res;<br />}<br /></blockquote><div class="quotefooter"><div class="botslice_quote"></div></div> </dd> <dt class="postheader"> Название: <strong>Чтение файлов из дир-ии и пр.</strong><br /> Отправлено: <strong>Mog.</strong> от <strong>08 Февраля 2003, 11:59:42</strong> </dt> <dd class="postbody"> <div class="quoteheader"><div class="topslice_quote">Цитировать</div></div><blockquote class="bbc_standard_quote">readdir читает все фалы из директории</blockquote><div class="quotefooter"><div class="botslice_quote"></div></div> Это в списковом констексте. А в скалярном возвращает очередное имя файла. А с помощью seekdir мона двигаться по каталогу на нужную позицию, не читая содержимое каталога целиком.<br />Т.е. <br />opendir (dir, "каталог");<br />seekdir dir, $x;<br />for ($a=0; $a < ($y-$x); $a++){ $dir[$a] = readdir (dir) }<br />closedir dir;<br /><br />и у тебя список файлов с x по y <br />При условии, что ты знаешь в какой последовательности у тебя файлы читаются readdir\'ом (лично я единства в этом на разных системах не заметил) </dd> </dl> <div id="footer" class="smalltext"> <span class="smalltext" style="display: inline; visibility: visible; font-family: Verdana, Arial, sans-serif;"><a href="http://forums.webscript.ru/index.php?action=credits" title="Simple Machines Forum" target="_blank" class="new_win">SMF 2.0.19</a> | <a href="http://www.simplemachines.org/about/smf/license.php" title="License" target="_blank" class="new_win">SMF © 2016</a>, <a href="http://www.simplemachines.org" title="Simple Machines" target="_blank" class="new_win">Simple Machines</a> </span> </div> </body> </html>