OberonCore https://forum.oberoncore.ru/ |
|
Порядок чтения из файла https://forum.oberoncore.ru/viewtopic.php?f=30&t=6050 |
Страница 1 из 1 |
Автор: | kekc_leader [ Вторник, 09 Май, 2017 00:20 ] |
Заголовок сообщения: | Порядок чтения из файла |
В книге «Программирование на Обероне» приведён такой пример чтения из файла (стр. 52): Цитата: The file can thereafter be read by the following pattern. First, the file with specified name is associated with variable f. Then a rider is placed at the start of the file, and then advanced by reading. Код: f := Files.Old(“MyFile”); Files.Set(r, f, 0); Note that the rider indicates that the end of the file had been reached after the first unsuccessful attemptWHILE ~r.eof DO Files.Read(f, next); process(next) END of reading. Тогда как в книге «Проект Оберон» приведён следующий пример (стр. 85): Код: VAR f: Files.File; r: Files.Rider; f := Files.Old(name); IF f # NIL THEN Files.Set (r, f, 0); Files.Read(r, x); WHILE ~ r.eof DO ... x ...; Files.Read(r, x) END END По-моему, в первой книжке ошибка, т. к. код не стыкуется с комментарием («Заметим, что бегунок указывает, достигнут ли конец файла, только после первой неудачной попытки чтения»). Вопрос: Надо ли производить вызов Files.Read до начала цикла? Понятно, что среди различных реализаций Оберона можно найти оба варианта, но интересней всего знать, как должно быть по науке. |
Автор: | Valery Solovey [ Вторник, 09 Май, 2017 01:06 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Зависит от спецификации. Лично мне больше нравится первый вариант, но он не всегда возможен или приемлем. |
Автор: | Александр Ильин [ Вторник, 09 Май, 2017 01:41 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Valery Solovey писал(а): Зависит от спецификации. Лично мне больше нравится первый вариант, но он не всегда возможен или приемлем. В первом варианте мне не нравится то, что process(next) вызывается даже в том случае, если последний Read ничего не прочитал. Т.е. непосредственно перед process(next) нет проверки r.eot.Поэтому я предпочитаю код вида Код: WHILE Files.Read(f, next) DO process(next) END Второй вариант ближе всего к этому.
|
Автор: | Илья Ермаков [ Вторник, 09 Май, 2017 02:38 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
На эту тему тут разбиралось: http://oberoncore.ru/wiki/%D0%BF%D0%B0% ... 0%BE%D0%B2 |
Автор: | Valery Solovey [ Вторник, 09 Май, 2017 21:19 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Александр Ильин писал(а): В первом варианте мне не нравится то, что process(next) вызывается даже в том случае, если последний Read ничего не прочитал. Cамый простой и эффективный способ понять, достигнут ли конец файла - это сравнить текущую позицию с размером файла. Если они равны, значит EOT. Но такой вариант не будет работать, например, с http-ответами или файловыми системами, где файл может быть больше максимального значения "размера файла" (поля в файловой записи).
|
Автор: | Valery Solovey [ Вторник, 09 Май, 2017 21:24 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Илья Ермаков писал(а): На эту тему тут разбиралось: Там разбирался общий случай, а это - частный.
http://oberoncore.ru/wiki/%D0%BF%D0%B0% ... 0%BE%D0%B2 |
Автор: | kekc_leader [ Четверг, 11 Май, 2017 23:49 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Вопрос, собственно, сводится к тому, как работает r.eof. Например, если мы только-только открыли файл и вызвали Files.Set(r, f, 0), а файл был пустым, будет ли значение r.eof = TRUE или сперва надо вызвать процедуру Files.Read(r, ch), а уж затем смотреть r.eof? Как должно быть? Заметку о шаблонах циклов много раз читал и всем показывал, очень хороший и ёмкий материал. Соответствующее обсуждение на форуме — тоже. |
Автор: | Иван Денисов [ Пятница, 12 Май, 2017 04:48 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
В первом случае предполагается, что в записях поля типа BOOLEAN устанавливаются при выделении памяти в FALSE. Поэтому первое чтение пройдет гарантированно. Также предполагается, что в process при этом есть корректная обработка ситуации с r.eof = TRUE. Второй же вариант более общий и не зависит от каких либо допущений о реализации компилятора и обработчика. Но тут нельзя сказать, что какой-то вариант более правильный. |
Автор: | Info21 [ Пятница, 12 Май, 2017 08:54 ] |
Заголовок сообщения: | "принцип нуля" |
kekc_leader писал(а): Вопрос, собственно, сводится к тому, как работает r.eof. Должно быть так, чтобы r.eof устанавливалось в TRUE только после попытки чтения.Например, если мы только-только открыли файл и вызвали Files.Set(r, f, 0), а файл был пустым, будет ли значение r.eof = TRUE или сперва надо вызвать процедуру Files.Read(r, ch), а уж затем смотреть r.eof? Как должно быть? Это частный случай принципа, что программа/процедура/etc. должна корректно отрабатывать "нулевой" случай. Польза от этого такая же, как от нуля в позиционной системе счисления: всё заметно упрощается и упорядочивается. Это не мешает делать любые оптимизации, потом. Или не делать ))) Полезно назвать это как-нибудь: скажем, принцип нуля. Об оптимизации тут речь, потому что в старых книгах, написанных во времена, когда вызов процедуры был дорог (включая виртовские "Алгоритмы ...", которые мне пришлось чистить), программы писали так, чтобы избегать "пустых" процедурных вызовов -- как раз для "нулевых" случаев. Тогда вместо одной проверки внутри рекурсивной процедуры нужно было не забыть поставить проверку-охрану перед любым вызовом -- а иногда эта проверка была не нужна по построению алгоритма, но при изменении про это можно было забыть -- и т.д. -- прямой путь в трясину "отладки". |
Автор: | Александр Ильин [ Пятница, 12 Май, 2017 11:15 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Иван Денисов писал(а): В первом случае предполагается, что в записях поля типа BOOLEAN устанавливаются при выделении памяти в FALSE. Замечу в этом месте, что в вызове "Files.Set(r, f, 0);" не происходит выделения памяти. В контексте ОС Оберон переменная r - это RECORD в стеке.
|
Автор: | albobin [ Пятница, 12 Май, 2017 11:51 ] |
Заголовок сообщения: | Re: Порядок чтения из файла |
Добавлю свои 2 коп. ИМХО " r.eof устанавливалось в TRUE только после попытки чтения." - это потому, что флаг (eof) должен выражать успешность/не успешность операции чтения по причине исчерпания доступных данных (в общем случае), а не отражать взаиморасположение текущей позиции для чтения и границы данных, которая (в общем случае) может динамично изменяться. PS. Сразу не прошёлся по ссылке из замечания И.Ермакова. Конечно типичный "полный проход". |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |