<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=299329</guid>
        <pubDate>Sat, 14 Feb 2004 16:42:22 +0000</pubDate>
        <title>Работа с файлами</title>
        <link>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=299329</link>
        <description><![CDATA[romtek: <span class='tag-size' data-value='12' style='font-size:12pt;'><strong class='tag-b'>Типизированные файлы</strong></span><br>
<br>
Новая версия находится в энциклопедии: <a class='tag-url' href='http://www.sources.ru/wiki/doku.php?id=pascal:files:typed' target='_blank'>Операции над типизированными файлами в Турбо Паскале</a>.<br>
<br>
Типичные операции с записями - это <strong class='tag-b'>добавление,изменение,удаление и вставка</strong> записей в файлах.<br>
Давайте рассмотрим структуру записей файла.<br>
<br>
Позиция при открытии файла<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;=========</div><div class="code_line">|*| | | | |</div><div class="code_line">&nbsp;=========</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
<strong class='tag-b'>1)</strong> Чтобы <span class="tag-color tag-color-named" data-value="blue" style="color: blue">добавить</span> запись в файл, необходимо сначала установить позицию в конец файла командой <em class='tag-i'>Seek</em> ,а затем производить запись с помощью <em class='tag-i'>Write</em>.<br>
<br>
Позиция в конце файла<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;=========</div><div class="code_line">| | | | | |*</div><div class="code_line">&nbsp;=========</div></ol></div></div></div></div><br>
Производим запись. Теперь добавилась ещё одна.<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;===========</div><div class="code_line">| | | | | | |*</div><div class="code_line">&nbsp;===========</div></ol></div></div></div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;Kurs: string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exams: array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var F: file of TStudentInfo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;st: TStudentInfo;</div><div class="code_line">begin</div><div class="code_line">.......</div><div class="code_line">&nbsp;&nbsp;Seek(F,FileSize(F)); { становимся в конец файла }</div><div class="code_line">&nbsp;&nbsp;Write(F,st); { записываем запись в файл }</div><div class="code_line">.......</div><div class="code_line">end.</div></ol></div></div></div></div> <br>
<br>
<strong class='tag-b'>2)</strong> Чтобы <span class="tag-color tag-color-named" data-value="blue" style="color: blue">подправить</span> запись, надо стать на позицию этой записи Seek(F,recordN), а затем производить запись. Аналогично предыдущему примеру, только вместо <strong class='tag-b'>Seek(F,FileSize(F));</strong> пишем <strong class='tag-b'>Seek(F,recordN);</strong>.<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>Не забывайте,</strong> что нумерация записей начинается <strong class='tag-b'>с нуля</strong>.</span><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;=========</div><div class="code_line">| | |*| | |</div><div class="code_line">&nbsp;=========</div></ol></div></div></div></div><br>
После того, как изменили запись, позиция продвинулась вперёд.<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;=========</div><div class="code_line">| | | |*| |</div><div class="code_line">&nbsp;=========</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>3)</strong> Если надо <span class="tag-color tag-color-named" data-value="blue" style="color: blue">найти</span> запись и исправить ее, надо: <ol class="tag-list" type="1"><li>установить позицию на начало, если необходимо (не надо когда только открыли файл для чтения)</li><li>проверять каждую запись по нужному критерию (имя, телефон и т.д.)</li><li>вернуться на одну позицию назад: Seek(F,FilePos(F)-1), т.к. после чтения записи с файла<br>
позиция уже продвинулась на следующую;</li><li>внести изменения в записи и затем производить запись в файл.</li><li>продолжать с пункта 2 пока не конец файла.</li></ol><strong class='tag-b'>Пример поиска и замены записи</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;Kurs: string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;Exams: array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: file of TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;st: TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;who: string[30];</div><div class="code_line">&nbsp;&nbsp;found: boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; write(&#39;Кого ищем? &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln(who);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if who=&#39;&#39; then exit;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; assign(f,&#39;students.dat&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; {$I-}</div><div class="code_line">&nbsp;&nbsp; &nbsp; reset(F);</div><div class="code_line">&nbsp;&nbsp; &nbsp; {$I+}</div><div class="code_line">&nbsp;&nbsp; &nbsp; found:=false;</div><div class="code_line">&nbsp;&nbsp; &nbsp; if IOresult=0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; with st do</div><div class="code_line">&nbsp;&nbsp; &nbsp; while Not EOF(F) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;read(F,st);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if name=who then &nbsp;{ нашли такого/ую }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write(&#39;Заменить на фамилию: &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; readln(name);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; found:=true; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; seek(F,FilePos(F)-1); { вернуться на 1 позицию обратно, т.е. на позицию того, что надо заменять }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write(f,st);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; { убрать это, если известно, что таких несколько }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; close(f);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if Not Found</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;then writeln(Who,&#39; не найден. Ха-ха&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else writeln(Who,&#39; найден и заменен.&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln(#13#10&#39;Жми Enter&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4)</strong> Вы спросите: &quot;А как же вставить или удалить запись в файле?&quot;<br>
Ответ:<br>
Файлы не имеют гибкой структуры данных, т.е. нельзя &quot;раздвинуть&quot; записи и вставить ещё одну,<br>
или удалить среди записей ненужную, подвинув остальные на место удалённой. То есть можно, но так не делается.<br>
В этом случае вам придётся создать второй файл, а прежний удалить.<br>
<br>
<strong class='tag-b'>0..i-1 , i , i+1..N</strong><ul class="tag-list"><li><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Удалить</span> запись <strong class='tag-b'>i</strong>:<br>
Записываем <strong class='tag-b'>0..i-1</strong>, пропускаем <strong class='tag-b'>i</strong>, а потом дописываем <strong class='tag-b'>i+1..N</strong>.<br>
</li><li><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Вставить</span> запись на место <strong class='tag-b'>i</strong>:<br>
Записываем <strong class='tag-b'>0..i-1</strong>, затем нужную запись, а потом дописываем <strong class='tag-b'>i..N</strong>.</li></ul>]]></description>
        <author>romtek</author>
        <category>Pascal: Файлы и записи</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=291522</guid>
        <pubDate>Sun, 01 Feb 2004 17:14:22 +0000</pubDate>
        <title>Работа с файлами</title>
        <link>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=291522</link>
        <description><![CDATA[Some1: Далее нам следует рассмотреть другие функции, которые определены в Паскале для удобства работы с файлами.<br>
<br>
Это функции:<br>
<strong class='tag-b'>Seek, FilePos, FileSize, Eof, SeekEof, EoLn, SeekEoLn, Delete, Rename</strong>. Вроде все.<br>
Будем расматривать по порядку.<br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'><div class='tag-align-center'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Seek</span></div></span><br>
Одна из наиболее часто используемых при работе с файлами комманда.<br>
Эта команда меняет в открытом файле текущее месторасположение.<br>
Работает только для файлов, открытых как типизированые или нетипизированные. Не работает в текстовых файлах. Файл должен быть открыт.<br>
<em class='tag-i'><strong class='tag-b'>Синтаксис:</strong></em><br>
<strong class='tag-b'>procedure Seek(&lt;Имя_дескриптора_файла&gt;,&lt;порядковый_номер_записи&gt;);</strong><br>
<br>
Эта процедура перемещает текущее положение в файле в запись с номером <strong class='tag-b'>&lt;порядковый_номер_записи&gt;</strong>. Положение в файле считается начиная с 0. Тоесть если мы хотим переместиться в начало файла <strong class='tag-b'>f</strong>, нам следует написать <strong class='tag-b'>Seek(f,0);</strong> Если хотим переместиться в 10 запись, то должны будем написать <strong class='tag-b'>Seek(f,9);</strong> Когда файл типизированный, записью считается тип файла, когда файл нетипизированный, то размер записи в байтах указывается при открытии файла (второй параметр команды открытия файла).<br>
<br>
Использование этой команды раскрывает очень широкие возможности в редактировании файла.<br>
При помощи неё стало возможным одновременное чтение и запись файла - то есть изменение его содержимого, и чтение в одном и том же файле.<br>
Вот классический пример:<br>
Пусть у нас файл состоит из 20 записей, каждая из которых - число. Нужно заменить нулём все записи, которые меньше нуля на ноль. Тоесть убрать отрицательные записи из файла.<br>
<br>
Можно конечно сделать так:<ol class="tag-list" type="1"><li>Прочесть все записи из файла в массив.</li><li>Пройтись по массиву, заменяя отрицательные записи на нули.</li><li>Открыть этот же файл командой <strong class='tag-b'>rewrite</strong> и записать заново все записи.</li></ol><br>
Но вот вам куда более удобный способ:<ol class="tag-list" type="1"><li>Читаем из файла текущую запись.</li><li>Если эта запись меньше нуля, то перемещаемся на одну запись назад командой <strong class='tag-b'>seek</strong>, и записываем в файл вместо отрицательной записи (которая у нас опять является текущей) запись с нулём.</li><li>повторяем до самого конца файла эти действия.</li></ol><br>
Такой подход даст значительно более быстро работающий результат.<br>
<br>
У вас может возникнуть один вопрос - откуда мы берём значение текущей записи, для того чтобы выполнить действие номер <strong class='tag-b'>2</strong>? Ведь нам чтобы сдвинуть номер записи назад, нужно знать номер текущей записи, иначе мы не сможем указать номер предыдущей записи. Можно конечно завести переменную, в которой содержать номер текущей записи, и изменять его в соответствии с алгоритмом. Однако это совершенно излишне, потому что именно для этого используется следующая команда.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">FilePos</span></span></div><br>
Эта команда используется для того чтобы узнать номер текущей записи в файле.<br>
Может быть использована только в типизированных и нетипизированных файлах. В текстовых файлах использовать нельзя (потому что в текстовых файлах нет понятия - запись).<br>
<span class='tag-u'>Записи в файле всегда нумеруются с нуля.</span> Эта особенность очень часто у новичков вызывает ошибки.<br>
Допустим в файле всего находится 10 записей. Тогда первой записью всегда будет запись номер 0, а последней не 10, как можно было бы подумать, а 9. Тоесть записи будут нумероваться - 0, 1, 2...9 Всего получится 10 номеров (Вместе с 0). Учтите это и при использовании <strong class='tag-b'>Seek</strong>.<br>
<em class='tag-i'><strong class='tag-b'>Синтаксис:</strong></em><br>
<strong class='tag-b'>function FilePos(&lt;переменная_дескриптор_файла&gt;):longint;</strong><br>
Как видите эта команда - функция. Возвращаемым ею значением и будет текущее положение в файле.<br>
Тут также следует учесть, что текущим положением в файле будет номер текущей записи в файле, а не порядковый номер байта. Когда я начинал работать, я долго не мог понять разницы. Байты - это вся информация в файле. А записи - это блоки, из которых он состоит. Одна запись может быть размером к примеру 5 байт. И если эта команда вернёт цифру 10, то это будет значить, что сейчас в файле активна 11 запись (смотрите, мы учитываем ноль, поэтому 11). А это получится 11*5=55. Значит в файле эта запись будет начинаться с 55 байта (если их считать начиная с 1).<br>
Теперь немного практики:<br>
Файл состоит из записей типа String[100].<br>
Найдём и заменим в нём все записи, в которых встречается слово &quot;ФИО&quot; На наше ФИО.<br>
Вот код:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;sof100=string[100]; {Это тип информации в файле - обязательно нужно объявить (см. пояснение)}</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: File of sof100;</div><div class="code_line">&nbsp;&nbsp;s: sof100; {запись из файла будет здесь}</div><div class="code_line">&nbsp;&nbsp;fio: string; {Наше ФИО}</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;write(&#39;Введём наше ФИО: &#39;);</div><div class="code_line">&nbsp;&nbsp;readln(fio);</div><div class="code_line">&nbsp;&nbsp;if length(fio)&#62;100 then fio:=copy(fio,1,100); {Обрежем лишние символы}</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;fio.dat&#39;);</div><div class="code_line">&nbsp;&nbsp;reset(f);</div><div class="code_line">&nbsp;&nbsp;while not eof(f) do {Этого мы ещё не прошли - цикл будет выполняться пока не окончится файл}</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;read(f,s);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if s=&#39;ФИО&#39; then {Если текущая запись - слово ФИО}</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;s:=fio; {Нужно преобразовать из строки в sof100, для этого присвоим s значение fio}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;seek(f,filepos(f)-1); {переместим позицию файла в позицию на один меньше текущей}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;write(f,s); {Перезапишем в файл наше ФИО}</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;close(f);</div><div class="code_line">end.</div></ol></div></div></div></div>В данном примере мы описали специально тип информации, который содержится в файле:<br>
<strong class='tag-b'>type sof100=string[100];</strong><br>
Дело в том, что если тип информации в файле описать как <strong class='tag-b'>string[100]</strong>, то это будет работать нормально но(&#33;) описав переменную <strong class='tag-b'>s:string[100]</strong> мы не сможем ни записать её в файл, ни прочесть в неё из него. Это происходит из-за того, что Паскаль считает, что тип данных в файле (<strong class='tag-b'>string[100]</strong>) это один тип данных, а тип переменной <strong class='tag-b'>s</strong> - (тоже <strong class='tag-b'>string[100]</strong>) это совсем другой тип данных. Тоесть для нас конечно же очевидно, что оба типа одинаковые, но для Паскаля это совсем не очевидно. Для него переменная <strong class='tag-b'>s</strong>, и данные в файле <strong class='tag-b'>f</strong> имеют различные типы, и следовательно в файл <strong class='tag-b'>f</strong> нельзя будет записать такую переменную <strong class='tag-b'>s</strong>. Поэтому нам необходимо объявить один общий тип - <strong class='tag-b'>type sof100=string[100];</strong> и создать типизированый файл такого типа, и переменную <strong class='tag-b'>s</strong> тоже такого типа. Тогда паскаль понимает, что и то, и то имеют один тип.<br>
Конечно же эта функция может быть использована только на открытых файлах.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">FileSize</span></span></div><br>
Эта команда позволяет определить количество записей в файле. Тоесть это можно назвать размером файла (в записях). Работает только для типизированных или нетипизированных файлов (не работает для текстовых) и файл должен быть <strong class='tag-b'>обязательно открыт</strong>.<br>
<em class='tag-i'><strong class='tag-b'>Синтаксис:</strong></em><br>
<strong class='tag-b'>function FileSize(&lt;переменная_дескриптор_файла&gt;):longint;</strong><br>
Как и <strong class='tag-b'>FilePos</strong> эта команда является фукнцией.<br>
Значение, которое она возвращает является количеством записей в файле на данный момент.<br>
Если в файле при открытии уже есть записи, то эта команда вернёт их количество. Если в течении работы с файлом это количество изменится (например мы добавим новые, или удалим старые) то при последующем вызове этой команды это изменение будет учтено. Поэтому можно сказать, что эта команда возвращает количество записей в файле на данный момент.<br>
Если при октрытии файла в нём находится информация не кратная размеру записей (ну например размер записи - 5, а в файле 27 байт - 5 записей и 2 байта), то функция вернёт количество <strong class='tag-b'>полных</strong> записей в файле (тоесть в данном примере - 5).<br>
Количество записей считается с 1. Поэтому проблемм с нулями тут обычно не возникает (как в командах <strong class='tag-b'>FilePos</strong> и <strong class='tag-b'>Seek</strong>).<br>
<br>
<span class="tag-color tag-color-named" data-value="red" style="color: red"><strong class='tag-b'>Не путайте</strong> - команда возвращает не размер файла в байтах, а <strong class='tag-b'>количество записей</strong></span> (разве что если размер записи - 1 байт %)) На первых парах начинающие программисты часто забывают о разнице.<br>
<br>
Для этой команды я приведу переведённый пример из стандартного паскалевского хелпа:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: file of Byte;</div><div class="code_line">&nbsp;&nbsp;size : Longint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Assign(f, ParamStr(1)); {Имя файла узнаем из командной строки программы}</div><div class="code_line">&nbsp;&nbsp;Reset(f); {Откроем файл с размером записи - 1 байт}</div><div class="code_line">&nbsp;&nbsp;size := FileSize(f); {В переменной будет находиться текущий размер открытого файла}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Размер файла в байтах: &#39;,size); {Выведем его}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Перейдём в середину файла...&#39;);</div><div class="code_line">&nbsp;&nbsp;Seek(f,size div 2); {Переходим}</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Position is now &#39;,FilePos(f)); {Выведем номер текущего положения в файле}</div><div class="code_line">&nbsp;&nbsp;Close(f); {Закроем файл}</div><div class="code_line">end.</div></ol></div></div></div></div>Я думаю, вопросов это не должно вызывать.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">EOF</span></span></div><br>
Это важная команда, которая повседневно применяется при работе с файлами (Я даже не смог обойтись без неё в предыдущих примерах, поэтому возможно вы уже догадались, что она делает).<br>
Расшифровывается так: <strong class='tag-b'>E</strong>nd <strong class='tag-b'>O</strong>f <strong class='tag-b'>F</strong>ile - EOF (конец файла)<br>
При помощи этой команды можно узнать, достигли ли мы конца файла.<br>
Допустим мы должны вывести всю информацию из файла на экран. Мы будем читать её из файла пока он не кончится. Для того, чтобы определить - когда-же у нас кончился файл мы должны использовать эту команду.<br>
<em class='tag-i'><strong class='tag-b'>Синтаксис</strong></em> такой:<br>
<strong class='tag-b'>function EOF(&lt;переменная_дескриптор_файла&gt;):boolean;</strong><br>
Всё просто. Команда возвращает <strong class='tag-b'>true</strong>, если файл кончился, и возвращает <strong class='tag-b'>false</strong>, если ещё не кончился.<br>
<strong class='tag-b'>Eof</strong> может использоваться для определения достижения конца <strong class='tag-b'>любого</strong> файла: будь то типизированный файл, нетипизированный файл, или даже <strong class='tag-b'>текстовый файл</strong>(учтите что и текстовый тоже).<br>
Команда не реагирует на символ #26 в текстовых файлах. Поэтому определить наличие этого символа при помощи <strong class='tag-b'>Eof</strong> нельзя. Однако если паскаль среагирует на этот символ, то произойдёт глюк (описаный в команде <strong class='tag-b'>write</strong> для текстового файла). Для файлов нетекстового типа проблемм с этим символом нет.<br>
Для типизированных и нетипизировнных файлов эта команда возвращает признак окончания файла, если текущее положение находится в конце файла. Если переместить текущее положение (командой <strong class='tag-b'>seek</strong>) в другое место файла, то после этого команда <strong class='tag-b'>Eof</strong> вернёт <strong class='tag-b'>false</strong><br>
Простейшим примером для команды будет программа, читающая и выводящая текстовый файл на экран, пока он не кончится.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: text;</div><div class="code_line">&nbsp;&nbsp;s: string;</div><div class="code_line">begin.</div><div class="code_line">&nbsp;&nbsp;assign(f,paramstr(1));</div><div class="code_line">&nbsp;&nbsp;reset(f);</div><div class="code_line">&nbsp;&nbsp;while not eof(f) do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;readln(f,s);</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(s);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;close(f);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<div class='tag-align-center'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='14' style='font-size:14pt;'>SeekEOF</span></span></div><br>
Команда является почти полным аналогом предыдущей. Однако есть и различия.<br>
Вопервых она может быть использована <span class="tag-color tag-color-named" data-value="red" style="color: red"><strong class='tag-b'>только</strong> для текстовых файлов</span>.<br>
И во вторых - при вызове этой команды не только возвращается признак окончания файла, а так-же пропускаются все символы, меньше #33 (пробелы и управляющие символы). Если в файле встречается символ #26, то эта функция возвращает <strong class='tag-b'>true</strong> - тоесть это признак конца файла. При помощи этой команды удобно читать из файла только буквы или цифры, пропуская пробелы, знаки табуляции, символы перехода строки. В результате можно получить текст &quot;сплошняком&quot;.<br>
Синтаксис аналогичен команде <strong class='tag-b'>Eof</strong>.<br>
Вот пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f: text;</div><div class="code_line">&nbsp;&nbsp;c: char;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;text.txt&#39;);</div><div class="code_line">&nbsp;&nbsp;reset(f);</div><div class="code_line">&nbsp;&nbsp;while not seekeof(f) do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;read(f,c);</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(c);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;close(f);</div><div class="code_line">end;</div></ol></div></div></div></div>Получится текст из файла, только не будут переноситься строки, не будут проставляться пробелы, потому что как только будет выполняться команда <strong class='tag-b'>SeekEof</strong>, так сразу все символы с кодом до #33 будут пропускаться, и в случае достижении конца файла функция вернёт значение <strong class='tag-b'>true</strong>.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">EoLn</span></span></div><br>
<br>
Далее следует. Временное сохранение.]]></description>
        <author>Some1</author>
        <category>Pascal: Файлы и записи</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=290603</guid>
        <pubDate>Fri, 30 Jan 2004 23:20:41 +0000</pubDate>
        <title>Работа с файлами</title>
        <link>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=290603</link>
        <description><![CDATA[Some1: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2. BlockRead и BlockWrite</strong></span><br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.1. Текстовые файлы</span><br>
Нельзя использовать.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.2. Типизированые файлы</span><br>
Также нельзя использовать.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.3. Нетипизированые файлы</span><br>
Только файлы такого типа можно использовать с этими двумя командами.<br>
Команда <strong class='tag-b'>BlockRead</strong> позволяет читать информацию из нетипизированного файла указанного размера. Вся прочтённая информация записывается в указанный буффер.<br>
<br>
<em class='tag-i'><strong class='tag-b'>Синтаксис:</strong></em><br>
<strong class='tag-b'>procedure BlockRead(&lt;дескриптор_нетипизированного_файла&gt;,&lt;буффер&gt;,&lt;количество_записей&gt;:word[,&lt;результат&gt;:word]);</strong><br>
<br>
Рассмотрим параметры по порядку:<ul class="tag-list"><li><strong class='tag-b'>&lt;дескриптор_нетипизированного_файла&gt;</strong> - ну это ясно. Это дескриптор файла, из которго производится чтение.</li><li><strong class='tag-b'>&lt;буффер&gt;:longint</strong> - это любая переменная паскаля. Буффером может быть например массив. Или переменная типа &quot;запись&quot;. Может быть строка, даже указатель. Паскаль не понимает, какой тип переменной в данном случае указан, и не производит перевода данных в соответствующий тип.<br>
Это значит, что если вы читаете этой командой из нетипизированного файла строку с текстом в текстовую переменную, то текст <strong class='tag-b'>не</strong> будет преобразован в текстовую переменную. Читаемая информация будет занесена в то место памяти, которое занимает текстовая переменная без всякого соблюдения её внутреннего синтаксиса. Чаще всего в этом параметре указывается массив какой либо информации, в связи с тем, что эта команда позволяет читать множество записей сразу (смотри следующий параметр).</li><li><strong class='tag-b'>&lt;количество_записей&gt;</strong> - этот параметр задаёт, сколько записей за раз следует прочитать из файла данным вызовом этой команды. Если там указана цифра 3, то из файла прочтутся 3 записи. Напомню, что для нетипизированных файлов размер записи определяется в момент его открытия (это второй параметр команд открытия файла). Если запись указана как число 3 - то это 3 байта. И если параметр <strong class='tag-b'>&lt;количество_записей&gt;</strong> в этом случае будет 10, то из файла будет прочтено 3*10=30 байт. Такой метод часто бывает удобен, если у вас в файле содержится набор одноразмерной информации. Допустим мы записали в файл массив из чисел типа longint, и сделали запись этих чисел в их внутреннем виде. На каждое число будет приходиться по 4 байта. Значит при открытии файла следует указать размер записи равным 4 байтам, а потом можно прочесть эти числа в массив, указав его имя в параметре <strong class='tag-b'>&lt;буффер&gt;</strong>, и количество элементов, которое мы хотим прочесть из файла в параметре <strong class='tag-b'>&lt;количество_записей&gt;</strong>. Данный параметр должен быть переменной или константой типа <strong class='tag-b'>word</strong>.</li><li><strong class='tag-b'>&lt;результат&gt;</strong> - этот параметр является необязательным. Его можно не указывать. Если же указывать, то это должна быть переменная типа <strong class='tag-b'>word</strong>. После выполнения процедуры <strong class='tag-b'>BlockRead</strong> в этой переменной будет содержаться фактическое число прочтённых полных записей из файла. Дело в том, что при чтении из файла мы можем запросить прочесть больше записей, чем на самом деле осталось в файле. И тогда мы дойдём до конца, и далее читать уже будет нечего. Так вот этот параметр будет содержать количество записей, которое нам удалось прочесть. Считаются только полные записи, тоесть те, которые дочитались до конца (файл может окончиться где-то в середине очередной записи).</li></ul><br>
После чтения очередной записи (или группы записей) команда BlockRead смещает указатель текущей позиции файла на количество_прочтённых_записей дальше.<br>
Суммарный размер информации, которую можно прочесть за раз этой командой не должен привышать 65535 байт, иначе возникнет ошибка. Это значит, что <strong class='tag-b'>Размер_записи*&lt;количество_записей&gt;</strong> должно быть меньше чем 65536.<br>
<br>
<em class='tag-i'><strong class='tag-b'>Пример</strong></em>: В файле содержится 13 байт: 1112223334445<br>
Смотрите, что мы получим читая его.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f:file; {Объявим дескриптор нетипизированного файла}</div><div class="code_line">&nbsp;&nbsp;b:array[1..100] of char;</div><div class="code_line">&nbsp;&nbsp;r:word;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;123.dat&#39;);</div><div class="code_line">&nbsp;&nbsp;reset(f,3); {Установим размер записи равным 3}</div><div class="code_line">&nbsp;&nbsp;blockread(f,d,2);</div><div class="code_line">&nbsp;&nbsp;{сейчас мы прочли две первые записи, тоесть 3*2=6 байт}</div><div class="code_line">&nbsp;&nbsp;{Эти 6 байт занеслись в первые 6 ячеек массива d - &quot;111222&quot;}</div><div class="code_line">&nbsp;&nbsp;blockread(f,d[7],10,r);</div><div class="code_line">&nbsp;&nbsp;{Теперь мы попытались прочесть ещё 10 записей из файла}</div><div class="code_line">&nbsp;&nbsp;{Но в файле осталось только 2 полные записи, и ещё одна неполная}</div><div class="code_line">&nbsp;&nbsp;{Поэтому переменная r будет содержать число 2}</div><div class="code_line">&nbsp;&nbsp;{А в массив начиная с 7 ячейки будут записаны ещё 7 байт}</div><div class="code_line">&nbsp;&nbsp;{Обратите на это внимание. Именно ещё 7 а не 6, как можно было бы предположить}</div><div class="code_line">&nbsp;&nbsp;...</div></ol></div></div></div></div><br>
<br>
Этой командой довольно удобно читать целые массивы каких либо типизированных данных.<br>
Нам нужно только знать, сколько байт в файле занимает информация об одном из типизированных данных.<br>
Помните раньше для типизированных файлов я давал пример - файл с данными о студентах и их оценках.<br>
Тип данных там был таким:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;name:string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;kurs:string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;ekz:array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div>Так вот из такого файла командой BlockRead можно прочесть сразу (например) 10 записей.<br>
<em class='tag-i'><strong class='tag-b'>Пример:</strong></em><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;name:string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;kurs:string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;ekz:array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f:file;</div><div class="code_line">&nbsp;&nbsp;st:array[1..10] of TSudentInfo;</div><div class="code_line">&nbsp;&nbsp;res:word;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;students.dat&#39;);</div><div class="code_line">&nbsp;&nbsp;{$I-} {Будем сами отслеживать ошибки}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;{Попробуем открыть файл}</div><div class="code_line">&nbsp;&nbsp;{Обратите внимание - здесь принципиально важное место. Мы открываем файл</div><div class="code_line">&nbsp;&nbsp; с размером записи, равным размеру записи TStudentInfo, что позволит читать</div><div class="code_line">&nbsp;&nbsp; нам за раз одну запись}</div><div class="code_line">&nbsp;&nbsp;reset(f,sizeof(TStudentInfo)); </div><div class="code_line">&nbsp;&nbsp;{$I+}</div><div class="code_line">&nbsp;&nbsp;if ioresult&#60;&#62;0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(&#39;Файл с данными не найден. Запустите сначала первую программу&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;exit; {Прервём выполнение программы}</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;{Теперь прочтём сразу 10 описаний студентов в массив st}</div><div class="code_line">&nbsp;&nbsp;blockread(f,st,10,res); {Читаем 10*размер_записи_о_студенте байт}</div><div class="code_line">&nbsp;&nbsp;{После выполнения blockread в переменной res находится количество удачно прочтённых записей}</div><div class="code_line">&nbsp;&nbsp;{Поскольку в файле может быть меньше 10 описаний, для нас это принципиальные данные}</div><div class="code_line">&nbsp;&nbsp;writeln(&#39;Из файла удалось прочесть информацию о ,&#39;res,&#39; студенте(ах)&#39;);</div><div class="code_line">&nbsp;&nbsp;close(f); {Эту команду мы ещё не рассматривали, но об этом я расскажу в конце}</div><div class="code_line">&nbsp;&nbsp;{Ну а теперь можно вывести информацию о res прочтённых студентах на экран}</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<br>
Ну и наконец команда <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>BlockWrite</strong></span><br>
<em class='tag-i'><strong class='tag-b'>Синтаксис:</strong></em><br>
<strong class='tag-b'>procedure BlockWrite(&lt;дескриптор_нетипизированного_файла&gt;,&lt;буффер&gt;,&lt;количество_записей&gt;:word[,&lt;результат&gt;:word]);</strong><br>
<br>
Эта команда имеет идиентичный синтаксис с командой <strong class='tag-b'>BlockRead</strong>.<br>
Команда записывает данные из памяти указанной параметром <strong class='tag-b'>&lt;буффер&gt;</strong> в файл, связанный с дескриптором <strong class='tag-b'>&lt;дескриптор_нетипизированного_файла&gt;</strong>. Как и в команде <strong class='tag-b'>BlockRead</strong> тут есть параметр <strong class='tag-b'>&lt;количество_записей&gt;</strong> типа <strong class='tag-b'>word</strong>, который указывает, сколько записей переписать из памяти в файл этой командой.<br>
Параметр <strong class='tag-b'>&lt;результат&gt;</strong> после выполнения процедуры содержит количество удачно записанных записей. Это значит, что в процессе записи в файл носитель информации может быть переполнен, и дальнейшая запись будет невозможной. Так вот в этом параметре будет содержаться количество целых записей, которые удалось занести в файл до того, как заполнился носитель информации. Тут следует учесть, что носитель информации может заполниться на середине очередной записи. Недописаная запись не будет удалена из файла, однако в параметре <strong class='tag-b'>&lt;результат&gt;</strong> она учтена не будет.<br>
Как и в команде <strong class='tag-b'>BlockRead</strong> параметр <strong class='tag-b'>&lt;результат&gt;</strong> не является обязательным, и его можно не указывать.<br>
<br>
Обе команды можно комбинировать, то читая, то записывая записи в файл.<br>
<br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">4. Закрытие файла</span></span></div><br>
Ну вот мы и добрались наконец к завершающей стадии работы с файлом.<br>
Это закрытие файла. После того, как информация, находящаяся в файле была должным образом обработана (или сформирована) файл обязательно следует закрыть. После закрытия файла все действия, проведённые нами с файлом вступят в силу. Не следует забывать этого действия, так как это может повлечь некоторые неприятные последствия. Во первых те изменения, которые вы поизвели в структуре файла могут не полностью сохраниться, и во вторых в системе файл останется открытым. А у каждой системы есть ограничение на возможное количество одновременно открытых файлов. Для ДОСа это 7 файлов (можно установить больше добавив в файл config.sys строку <strong class='tag-b'>files=20</strong>). Для Windows больше, но всё же совершенно очевидно, что файл следует закрыть после работы с ним. Иначе после определённого количества запусков вашей программы в системе будет максимум открытых файлов, и в конце концов наступит момент, что система не сможет открыть ещё один.<br>
Файл любого типа закрывается командой <strong class='tag-b'>Close</strong>, которая имеет простой синтаксис:<br>
<br>
<strong class='tag-b'>procedure Close(&lt;дескриптор_открытого_файла&gt;);</strong><br>
Попытка закрыть уже закрытый (либо ещё не открытый) файл не приводит ни к каким последствиям. Это бывает в некоторых случаях удобно.]]></description>
        <author>Some1</author>
        <category>Pascal: Файлы и записи</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=289968</guid>
        <pubDate>Thu, 29 Jan 2004 22:34:41 +0000</pubDate>
        <title>Работа с файлами</title>
        <link>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=289968</link>
        <description><![CDATA[Some1: <div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">3. Запись или чтение информации из файла</span></span></div><br>
<br>
После того как вы описали дескриптор файла, после того как вы его связали с реальным файлом, после того как вы открыли это файл наконец можно начать запись или чтение из него.<br>
<br>
В паскале есть два стандартных набора команд для работы с информацией в файлах.<br>
Это:<br>
1. <strong class='tag-b'>Write</strong> и <strong class='tag-b'>Writeln</strong>, <strong class='tag-b'>Read</strong> и <strong class='tag-b'>Readln</strong><br>
2. <strong class='tag-b'>BlockRead</strong> и <strong class='tag-b'>BlockWrite</strong><br>
То, как они работают целиком и полностью зависит от типа дескриптора файлов. Либо дескриптор файла текстовый, либо содержит типизированную информацию, либо нетипизированную. Для каждого из видов я опишу специфику работы этих команд.<br>
<br>
Начнём по порядку:<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1. Write и Writeln, Read и Readln</strong><br>
1.1. Текстовые файлы</span><br>
<br>
В файлах, открытых как текстовые можно применять эти четыре команды с таким же результатом как и их применение для вывода (либо ввода) на экран. Применение команд Write и Writeln рассмотрено в статье нашего FAQ: <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=39965' target='_blank'>Как вывести текст (строку) ?</a><br>
В синтаксисе следует учесть, что перед тем, как указывать что выводить, или куда вводить информацию нужно указать дескриптор файла, с которым мы работаем.<br>
Вот пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Writeln(f1,&#39;Эта строка окажется внутри файла с дескриптором f1&#39;);</div></ol></div></div></div></div><br>
Точно так же как и на экране эта команда занесет данную строку в файл, после чего перейдет на новую строку файла.<br>
При чтении из файла так же как и при чтении с клавиатуры следует соблюдать, чтобы тип информации совпадал с типом переменной, в которую мы хотим считать информацию.<br>
Например если в файле находится три строки, то прочесть их в переменную типа &quot;число&quot; скорее всего будет нельзя (если конечно в строках не содержатся числа).<br>
Например в файле такие данные:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Это строка</div><div class="code_line">12321</div><div class="code_line">Это было число</div><div class="code_line">А вот это будет три символа:</div><div class="code_line">№%@</div></ol></div></div></div></div><br>
Можно прочесть такую информацию вот так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f:text;</div><div class="code_line">&nbsp;&nbsp;s1,s2,s3:string;</div><div class="code_line">&nbsp;&nbsp;v1:longint;</div><div class="code_line">&nbsp;&nbsp;c1,c2,c3:char;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#60;тут имя файла&#62;);</div><div class="code_line">&nbsp;&nbsp;reset(f);</div><div class="code_line">&nbsp;&nbsp;readln(f,s1); {s1 &#60;- &quot;Это строка&quot;}</div><div class="code_line">&nbsp;&nbsp;readln(f,v1); {v1 &#60;- 12321}</div><div class="code_line">&nbsp;&nbsp;readln(f,s2); {s2 &#60;- &quot;Это было число&quot;}</div><div class="code_line">&nbsp;&nbsp;readln(f,s3); {s3 &#60;- &quot;А вот это будет три символа:&quot;}</div><div class="code_line">&nbsp;&nbsp;readln(f,c1,c2,c3); {c1 &#60;- &quot;№&quot;, c2 &#60;- &quot;%&quot;, c3 &#60;- &quot;@&quot;}</div><div class="code_line">&nbsp;&nbsp;...{остальные действия}</div><div class="code_line">end.</div></ol></div></div></div></div><br>
При чтении как и с клавиатуры можно комбинировать.<br>
Например такая инфа<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">1234 Я -3.14</div></ol></div></div></div></div> может быть прочтена вот так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;v:word;</div><div class="code_line">&nbsp;&nbsp;c:char;</div><div class="code_line">&nbsp;&nbsp;r:real;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;read(f1,v,c,r);</div><div class="code_line">...</div></ol></div></div></div></div><br>
<span class="tag-color tag-color-named" data-value="green" style="color: green">При работе с файлом таким образом следует помнить, что это не экран, и применять команды <strong class='tag-b'>gotoxy, clreol, clrscr</strong> нельзя. Они действуют только для информации на экране.</span><br>
<br>
Есть одна особенность при чтении из текстовых файлов:<br>
Признаком конца обычных файлов является достижение реального конца файла. Признаком достижения текстового файла могут быть две вещи: либо достижение реального конца файла, либо чтение из файла символа #26. Дело в том, что этот символ (стрелочка вправо) для текстовых файлов считается признаком конца файла. И если при чтении информации из файла (открытого как текстовый) встретится этот символ, то паскаль решит, что файл кончился, хотя на самом деле после этого символа может быть и остальная информация, и дальнейшее чтение уже не будет давать никакого результата. И даже более того: Если попытаться прочесть из файла этот символ не проверив перед этим, кончился ли файл, то это повлечет за собой такой глюк: в паскале прекратится выполнение каких либо действий с файлом, и вывод любой информации на экран. Следовательно старайтесь проверять перед чтением текстового файла, не кончился ли он.<br>
А что же делать, если нам нужно читать из файла текстовую информацию, включая и символ #26?<br>
определение символа #26 как конца файла происходит только в том случае, если данные из файла читаются в числовую переменную.<br>
к примеру в файле первый символ - #26<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;v1:byte;</div><div class="code_line">&nbsp;&nbsp;v2:longint;</div><div class="code_line">&nbsp;&nbsp;v3:real;</div><div class="code_line">&nbsp;&nbsp;c:char;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;read(f,v1); или read(f,v2); или read(f,v3); {Даст глюк с концом файла}</div><div class="code_line">&nbsp;&nbsp;read(f,c); или read(f,s1); read(f,s2); {Глюка не будет. Символ #26 займет свое место}</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.2. Типизированные файлы</span><br>
Это файлы с типизированным форматом данных.<br>
При объявлении дескриптора таких файлов указывается тип данных, содержащихся в файле.<br>
Для файлов такого типа возможно использование <strong class='tag-b'>только</strong> команд <strong class='tag-b'>read</strong> и <strong class='tag-b'>write</strong> из данной категории. (ReadLn и WriteLn нельзя). Такое ограничение очевидно. Поскольку данные в файле это не строки текста, то нет и линий. А значит нельзя переходить по линиям.<br>
Команда <strong class='tag-b'>Read</strong> читает одну или несколько записей из файла в переменную (или переменные). Тип переменных, в которые читается запись должен совпадать с типом типизированного дескриптора файла. Если вы объявили файл как <strong class='tag-b'>file of char</strong>, то читать из файла в переменные типа <strong class='tag-b'>string</strong> нельзя Можно только в char.<br>
Команда <strong class='tag-b'>write</strong> напротив записывает в файл одну или несколько переменных. Так же как и в команде <strong class='tag-b'>read</strong> типы переменных должны быть такими же как и тип данных файла.<br>
Данные в файле хранятся в внутреннем машинном виде. Поэтом раскрыв файл, в котором записаны переменные типа <strong class='tag-b'>word</strong> (к примеру) вы не увидите привычных цифр. Вместо них в файле будет всякая абракадабра. Это и есть внутреннее представление переменных типа <strong class='tag-b'>word</strong>. То, в каком виде они записаны в памяти. В данном примере на каждую переменную типа word будет отведено по два значка (байта). Количество байт, которое переменная занимает в памяти можно прочесть в хелпе по переменным паскаля, вызвав его из паскаля. Например введите слово <strong class='tag-b'>Real</strong>, наведите на него курсор и нажмите <strong class='tag-b'>Ctrl+F1</strong>. Вы увидите описание переменных с плавающей запятой. Там будет небольшая табличка для различных переменных, их максимальных и минимальных значений, а так же в столбце под названием <strong class='tag-b'>Bytes</strong> указано количество байт, которое занимает каждый из типов таких чисел в памяти. Для числа <strong class='tag-b'>Real</strong> это 6 и значит если файл будет описан как <strong class='tag-b'>file of real</strong>, то каждая запись в файл одной переменной типа <strong class='tag-b'>Real</strong> будет добавлять в него 6 байт, соответствующих значению этой переменной. При чтении такой записи из файла будет взято 6 байт, и занесены в то место памяти, где находится переменная, в которую мы читаем. Таким образом в этой переменной окажется то самое число типа <strong class='tag-b'>Real</strong>.<br>
Теперь важная информация:<br>
Если текущим местом в файле не является конец, а к примеру середина, то с чтением у нас нет вопросов. При чтении мы будем читать текущую запись, следующую после нее, и так далее до конца файла. А что же будет если мы попробуем записать запись в файл? Если вы подумали, что информация после текущего места сдвинется дальше, чтобы дать место для записи, которую мы пытаемся записать, то вы ошибаетесь. Если попытаться записать запись не в конец файла, а в какое-либо другое место, то текущая запись будет затерта той, которую мы записываем.<br>
Поясню на примере.<br>
Допустим у нас такой файл:<br>
В файле в машинном виде содержится четыре числа типа <strong class='tag-b'>Byte</strong> - 10 20 30 40<br>
На каждое из этих чисел в памяти приходится по одному байту. Поэтому в файле будет 4 байта.<br>
Допустим мы прочли из такого файла две переменные типа byte. Значит сейчас мы находимся на 3 переменной, но еще не читали ее.<br>
Если мы сейчас запишем в файл скажем вот такой командой: <strong class='tag-b'>write(f,0)</strong> то в файле не станет 5 чисел. В нем их останется по прежнему 4, но третья текущая запись будет заменена новой, то есть числом типа byte равным нулю (как у нас написано). И в файле получится вот такая информация: 10 20 0 40 (Естественно в машинном виде) то есть тоже 4 байта, но один из них будет уже другим.<br>
<br>
Для того, чтобы вставлять в середину файла какую либо информацию сдвигая всю следующую дальше следует использовать более сложные уловки, о которых я (может быть) расскажу позже.<br>
Приведу пример:<br>
Создадим файл, в котором будет список студентов и результаты их зачетов по 5 предметам.<br>
И напишем программу, которая бы выводила эти данные.<br>
Вот программа, которая создает файл с описанием студентов:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;name:string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;kurs:string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;ekz:array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f:file of TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;st:TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;p:byte;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;students.dat&#39;);</div><div class="code_line">&nbsp;&nbsp;{$I-} {Будем сами отслеживать ошибки}</div><div class="code_line">&nbsp;&nbsp;reset(f); {Откроем файл. Позиция на данный момент в самом начале}</div><div class="code_line">&nbsp;&nbsp;{$I+}</div><div class="code_line">&nbsp;&nbsp;if ioresult&#60;&#62;0 then rewrite(f); {Если ошибка, занчит файла нет, и значит откоем его подругому}</div><div class="code_line">&nbsp;&nbsp;seek(f,filesize(f)); {Если мы открыли файл первым способом, то значит он уже был и значит там</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;есть записи. Следовательно &nbsp;переместимся в его конец чтобы дописывать студентов}</div><div class="code_line">&nbsp;&nbsp;with st</div><div class="code_line">&nbsp;&nbsp;do repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(&#39;Введите имя студента (пустую строку для выхода): &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;readln(name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if name=&#39;&#39; then break;</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(&#39;Введите курс:&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;readln(kurs);</div><div class="code_line">&nbsp;&nbsp; &nbsp;for p:=low(ekz) to high(ekz) do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;write(&#39;Введите оценку по экзамену №&#39;,p,&#39;: &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;readln(ekz[p]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(f,st); {Вот эта строка и записывает информацию о студенте в файл}</div><div class="code_line">&nbsp;&nbsp;until false;</div><div class="code_line">&nbsp;&nbsp;close(f); {Эту команду мы ещё не рассматривали, но об этом я расскажу в конце}</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
А вот программа, которая читает и выводит эту информацию из файла:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TStudentInfo=record</div><div class="code_line">&nbsp;&nbsp; &nbsp;name:string[30];</div><div class="code_line">&nbsp;&nbsp; &nbsp;kurs:string[20];</div><div class="code_line">&nbsp;&nbsp; &nbsp;ekz:array[1..5] of byte;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;f:file of TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;st:TStudentInfo;</div><div class="code_line">&nbsp;&nbsp;p:byte;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;assign(f,&#39;students.dat&#39;);</div><div class="code_line">&nbsp;&nbsp;{$I-} {Будем сами отслеживать ошибки}</div><div class="code_line">&nbsp;&nbsp;reset(f); {Попробуем открыть файл}</div><div class="code_line">&nbsp;&nbsp;{$I+}</div><div class="code_line">&nbsp;&nbsp;if ioresult&#60;&#62;0 then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(&#39;Файл с данными не найден. Запустите сначала первую программу&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;exit; {Прервём выполнение программы}</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;with st do</div><div class="code_line">&nbsp;&nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;read(f,st); {Вот эта строка читает информацию о студенте из файла в st}</div><div class="code_line">&nbsp;&nbsp; &nbsp;writeln(&#39;Имя студента: &#39;,name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(&#39;Курс:&#39;,kurs);</div><div class="code_line">&nbsp;&nbsp; &nbsp;for p:=low(ekz) to high(ekz) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;write(&#39;Оценка по экзамену №&#39;,p,&#39;: &#39;,ekz[p]);</div><div class="code_line">&nbsp;&nbsp;until eof(f); {Эта команда ещё не рассмотрена, она будет возвращать неправду пока файл не кончится}</div><div class="code_line">&nbsp;&nbsp;close(f); {Эту команду мы ещё не рассматривали, но об этом я расскажу в конце}</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Поэкспериментируйте с программами, найдите их слабые места. Попробуйте от них избавитья %)<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">1.3. Нетипизированные файлы</span><br>
С файлами такого рода нельзя использовать первую группу команд. То есть, команды <strong class='tag-b'>write</strong>, <strong class='tag-b'>writeln</strong>, <strong class='tag-b'>read</strong> и <strong class='tag-b'>readln</strong>. Такое ограничение происходит потому что не известен тип записи в файле, а значит и неизвестен тип переменной в которую нужно было бы указывать в этих командах.<br>
<br>
На самом деле я кривлю душой, говоря о том, что неизвестен тип, и поэтому нельзя использовать эти команды. Потому что в принципе тип - это байт, или несколько байт. И чтение либо запись в файлы такого типа запросто можно было бы осуществить. Но... но увы в паскале видимо программисты не додумались, либо не захотели думать об этом. Посему данное ограничение пусть остаётся на их совести.]]></description>
        <author>Some1</author>
        <category>Pascal: Файлы и записи</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=284688</guid>
        <pubDate>Tue, 20 Jan 2004 23:02:16 +0000</pubDate>
        <title>Работа с файлами</title>
        <link>https://forum.sources.ru/index.php?showtopic=43464&amp;view=findpost&amp;p=284688</link>
        <description><![CDATA[Some1: Работа с файлами это объемная тема. И совсем не просто охватить ее целиком и полностью в одном топике. Однако я попытаюсь.<br>
<br>
Для того, чтобы работать с файлами в Паскале мы сначала должны определить тип информации, с которым мы собираемся работать. То есть, мы должны сразу же решить, какого типа информацию содержит (или будет содержать) файл. Это нам нужно сделать потому, что Паскаль поддерживает <strong class='tag-b'>три</strong> разных подхода для работы с файлами (забегая далеко вперед - для знающих Паскаль - я уточню, что я намерено опускаю работу с потоками, поскольку это данном случае только усложнит ситуацию, и потоки целесообразнее рассмотреть в отдельном топике). И для разного типа информации желательно использовать наиболее подходящие подходы.<br>
<br>
Паскаль умеет рассматривать информацию, находящуюся в файлах с таких точек зрения:<br>
<ul class="tag-list"><li><strong class='tag-b'>Текстовая информация</strong> - в файле находится (или будет находиться) текст. Под текстом я понимаю набор строк из символов. Каждая строка начинается с новой строки (простите за тавтологию).<br>
<br>
Текст не обязательно должен быть из букв. В нем могут содержаться и числа, и любые другие символы из таблицы ASCII, и на самом деле информацией в файле может быть совсем и не текст в привычном понимании этого слова. В файле может быть любая информация, но Паскаль может ее рассматривать (и, соответственно, имеет набор функций и процедур для ее обработки) как обычный текст.<br>
</li><li><strong class='tag-b'>Типизированная информация</strong> - в файле находится (или будет находиться) информация любого рода. Но структура такой информации обязательно должна повторяться. То есть, файл должен состоять из 1 и более одинаково устроенных частей. Например, файл может содержать различные строки из 20 символов. Тогда такой файл можно рассмотреть (и было бы лучше рассмотреть) как типизированный.<br>
<br>
Такое название (типизированный) файл получил из-за того, что в нем хранится однотипная информация. Типом данных для такого файла будет являться тот тип, какой имеет набор его частей. Проще говоря, если файл состоит из строк по 20 символов каждая, то типом информации в таком файле будет &quot;строка в 20 символов&quot;. И такой файл можно называть типизированным файлом по типу - строка из 20 символов. Одна ячейка такого типа называется <strong class='tag-b'>записью типизированного файла</strong> (или просто запись).<br>
<br>
Типизированные файлы очень часто используются для описания каких либо списков информации - например в телефонных справочниках. В файле - &quot;базе данных телефонов&quot; - содержится много записей, каждая из которых содержит в себе телефон абонента, имя, адрес, примечание, еще что либо.<br>
<br>
При работе с типизированными файлами можно читать из них (или писать в них) только записи целиком. То есть, в примере с базой телефонов, нельзя работая с ней, как с типизированным файлом: вписать в него только имя, или только телефон. Можно либо прочесть, либо записать одну из записей одним махом. Но никак не по частям. Зато можно прочесть целую запись, изменить например имя, и потом записать ее назад.<br>
</li><li><strong class='tag-b'>Нетипизированная информация</strong> - файл содержит любую информацию, не поддающуюся какой либо классификации. Например набор личных данных, машинный код, закодированный или сжатый блок информации. При работе с таким файлом вся информация рассматривается как набор кусков по <strong class='tag-b'>n</strong> байт, где <strong class='tag-b'>n</strong> в диапазоне от 1 до 65535. Значение <strong class='tag-b'>n</strong> определяется Вами, то есть Вы решаете, по сколько байт можно читать или писать в файл сразу. Содержимое этих кусков по <strong class='tag-b'>n</strong> байт определяете тоже Вы для себя. Вы можете рассматривать содержимое как Вам будет удобно. То ли это часть слова, то ли часть внутреннего (машинного) представления числа, то ли символ, то ли массив.</li></ul><br>
Итак, когда Вы определитесь, каким образом Вы собираетесь работать с файлом, тогда можно начинать работу.<br>
<br>
В самом начале нужно знать, что Паскаль не работает с файлом напрямую. Он работает с так называемым <strong class='tag-b'>дескриптором файла</strong>. Дескриптор файла - это переменная, которая описывает <strong class='tag-b'>конкретный</strong> файл, который Вы собираетесь обрабатывать. Дескриптор Вы должны создать сами, точно так же как Вы описываете любую другую переменную. Тип дескриптора будет определять, каким именно образом Вы собираетесь работать с файлом (один из трех способов, описанных выше).<br>
<br>
Есть три типа (в соответствии с тремя способами):<ul class="tag-list"><li><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;имя_переменной_дескриптора&#62;: Text;</div></ol></div></div></div></div> - соответствует файлу с текстовой информацией</li><li><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;имя_переменной_дескриптора&#62;: File of &#60;любой_тип_данных_паскаля&#62;;</div></ol></div></div></div></div> - соответствует типизированному файлу. В таком файле будут содержаться записи, тип которых будет определять параметр <em class='tag-i'>&lt;любой_тип_данных_паскаля&gt;</em>. Как было сказано ранее, файл будет состоять из таких записей. Все они <strong class='tag-b'>должны</strong> иметь один и тот же размер. Тип записи может быть любым - строка, символ, число, может быть составной сложный тип record. Тут следует сказать, что эти данные в файле должны храниться в машинном виде. То есть в том виде, в котором они находятся в памяти компьютера. При записи в типизированный файл данные автоматически конвертируются в такой вид и записываются. При чтении они автоматически загружаются в память в переменную, в которую мы читали. Например если файл состоит из чисел типа integer, то при записи в файл одной такой записи в нем добавится два байта - эти два байта и являются числом integer в машинном представлении. При чтении из файла такой записи в переменную типа integer данные должным образом перенесутся в эту переменную. можно попробовать записать в файл переменную типа word (которая тоже занимает 2 байта), а потом прочесть ее из файла как переменную типа integer, и это у нас получится &#33;&#33; Но при некоторых значениях этого числа данные будут искажены, так как у integer другой диапазон значений по сравнению с word. Есть исключения на тип данных записей, но они очевидные - например запись не может быть типа - file, или text, то есть файлового типа. Ведь файл не может состоять из файлов.</li><li><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;имя_переменной_дескриптора&#62;: File;</div></ol></div></div></div></div> - соответствует нетипизированному файлу. У такого файла данные не имеют типа, поэтому при задании дескриптора файла он не указывается. Считается что одна запись - это 1 или более байт (сколько именно определяется позже).</li></ul><br>
Когда мы опишем такой дескриптор, у нас появится переменная, которую мы сможем указывать при работе с файлом, и она будет однозначно определять <strong class='tag-b'>конкретный</strong> файл.<br>
Вот примеры описания файловых дескрипторов:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp; &nbsp;OnePhoneData=record &nbsp; &nbsp; &nbsp; &nbsp; { Запись-описание абонента }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Number:longint; &nbsp; &nbsp; &nbsp; &nbsp; { Его телефон }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Name:string[100]; &nbsp; &nbsp; &nbsp; { Его ФИО }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Address:string[200]; &nbsp; &nbsp;{ Его адрес }</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; &nbsp;TextFile:text; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Файл с текстовой информацией }</div><div class="code_line">&nbsp;&nbsp; &nbsp;PhoneFile: file of OnePhoneData; &nbsp; &nbsp;{ Файл с записями типа OnePhoneData }</div><div class="code_line">&nbsp;&nbsp; &nbsp;SomeData: file; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Файл с неопределённой информацией }</div><div class="code_line">&nbsp;&nbsp; &nbsp;Values: file of longint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Файл, состоящий из чисел (в их машинном представлении) }</div></ol></div></div></div></div><br>
В этом примере описаны четыре различных файловых дескриптора. Каждый из них определяет различные типы информации, содержащиеся в файле.<br>
<br>
После того, как мы написали такие дескрипторы мы можем начинать работать с файлом.<br>
<br>
Для любого файла нужно выполнять последовательность действий в процессе работы. Вот эта последовательность:<ul class="tag-list"><li>Связать дескриптор и конкретный файл на компьютере</li><li>Открыть файл</li><li>Записать в файл или прочесть из него информацию</li><li>Закрыть файл</li></ul>Менять местами пункты нельзя. Рассмотрим каждый по очереди, но прежде я хочу сделать небольшое отступление по поводу работы с информацией в файле:<br>
<br>
Для каждого файла при чтении или записи информации есть такое понятие, как текущее положение в файле. Текущее положение в файле это то положение, в котором на данный момент идет обработка информации. То есть Вы же понимаете, что вся информация состоит из частей, и все их сразу обрабатывать невозможно. Мы разбиваем всю информацию файла на одинаковые по размеру блоки, и далее работаем с этими блоками. Например если файл текстовый - то по буквам. Если файл типизированный - то по записям. Если нетипизированный - то по группам байт (нетипизированным записям). Так вот к примеру в типизированном файле мы можем прочесть первую запись, затем вторую, затем третью и так далее. И тогда текущим положением в файле сначала будет первая запись, потом вторая (когда мы первую уже прочтем), затем третья. В большинстве случаев за этим положением следить нет необходимости. То есть, после чтения из файла текущее положение автоматически изменяется на следующее. И так можно читать последовательно каждую запись, не заботясь о текущем положении. Но забегая вперед скажу, что иногда полезно бывает изменить текущее положение в файле, для того чтобы переписать к примеру запись в середине файла, когда мы уже находимся в конце.<br>
<br>
Чтобы исчерпать вопрос скажу, что текущее положение может быть началом файла, или самым концом файла. Если текущее положение уже конец файла, то последующее чтение из него ни к чему не приведет. А вот запись в него увеличит размер файла на записываемый кусок информации, после чего текущее положение изменится, и будет опять указывать в конец файла.<br>
Ну а теперь по пунктам работы с файлом:<br>
<br>
<hr><br>
<br>
<div class='tag-align-center'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='14' style='font-size:14pt;'>1. Связь дескриптора и конкретного файла на компьютере</span></span></div><br>
<br>
После выполнения этих действий дескриптор уже не будет абстрактной переменной. Он будет обозначать конкретный файл на компьютере. А тип этого дескриптора будет определять, каким образом интерпретировать (понимать и обрабатывать) информацию в этом файле.<br>
<br>
Для дескрипторов любого типа связь с файлом осуществляется одной командой:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Assign(&#60;имя_переменной_дескриптора&#62;, &#60;строка_имя_файла&#62;);</div></ol></div></div></div></div>Параметры:<br>
<em class='tag-i'>&lt;имя_переменной_дескриптора&gt;</em> - это, собственно, и есть дескриптор, который мы объявили ранее;<br>
<em class='tag-i'>&lt;строка_имя_файла&gt;</em> - это либо константа, либо переменная-строка, содержащая в себе имя файла, с которым мы хотим осуществить связь. В этой строке может также указываться и путь к файлу. Если он не указан, то считается, что файл находится в той же папке, что и программа.<br>
<br>
Вот несколько разных примеров:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp; &nbsp;filename1=&#39;myfile.txt&#39;;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp; &nbsp;Rec = record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;tel: longint; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;name: string; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;addr: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; &nbsp;f:file of byte;</div><div class="code_line">&nbsp;&nbsp; &nbsp;tel:file of Rec;</div><div class="code_line">&nbsp;&nbsp; &nbsp;dat:text;</div><div class="code_line">&nbsp;&nbsp; &nbsp;s:string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;s := &#39;d:\telbase&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;assign(f,&#39;ByteData.dat&#39;); &nbsp; { Теперь переменная f - это файл bytedata.dat, и состоит из байт }</div><div class="code_line">&nbsp;&nbsp; &nbsp;assign(tel,s+&#39;\Phones.db&#39;); { tel это файл с телефонами и обонентами. Находится в d:\teldata\phones.dat }</div><div class="code_line">&nbsp;&nbsp; &nbsp;assign(dat,filename1); &nbsp; &nbsp; &nbsp;{ dat - это текстовый файл myfile1.txt }</div><div class="code_line">&nbsp;&nbsp; &nbsp;... &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {Тут идёт работа с файлами}</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Надеюсь у вас не возникло вопросов. Потому что мы переходим к следующей более сложной части:<br>
<br>
<hr><br>
<div class='tag-align-center'><span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">2. Открытие файла на чтение и/или запись</span></span></div><br>
После того, как мы связали дескриптор файла с конкретным файлом этот дескриптор у нас уже считается тем самым файлом.<br>
Для того, чтобы работать с информацией, содержащейся в нем, нам нужно его открыть. Без этого ни запись, ни чтение информации из файла невозможно, и если забыть этот пункт, то ваша программа скорее всего завершится внутренней ошибкой.<br>
<br>
Файлы нужно открывать для того, чтобы указать системе, что Вы в данный момент используете файл. И тогда другие программы (если у вас windows) или резиденты (если DOS) не смогут менять содержимое файла, так как после его открытия к содержимому файла имеете доступ только вы.<br>
<br>
Именно когда Вы открываете файл, Вы определяете, каким образом Вы собираетесь манипулировать с информацией. Например Вам может быть нужно писать в файл, или читать из файла. А может быть и читать и писать сразу.<br>
<br>
Любая команда открытия файла открывает его, после чего в него можно писать и читать информацию. Но правда есть исключения - в некоторых случаях можно только читать, в некоторых только писать.<br>
<br>
Всего существует три команды открытия файлов. И хотя каждая позволяет и читать и писать, но чаще всего в силу их специфики одни используются исключительно для записи, другие исключительно для чтения, хотя я хочу сделать акцент на том, что это не является обязательным правилом, а во многих случаях правильнее и писать и читать из файла поочередно, не переоткрывая его разными командами.<br>
<br>
Один и тот же файл нельзя открыть одновременно двумя разными способами.<br>
<br>
Первая команда:<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Rewrite</span></strong><br>
Эта команда создает (если файла с таким именем еще нет) и открывает файл.<br>
Синтаксис:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Rewrite(&#60;название_дескриптора_файла&#62;[, &#60;размер_записи&#62;]);</div></ol></div></div></div></div><br>
Как видно из формата, в этой команде следует указать дескриптор файла, который мы хотим открыть.<br>
Параметр <em class='tag-i'>&lt;размер_записи&gt;</em> можно задавать <strong class='tag-b'>только</strong> если дескриптором файла является дескриптор нетипизированного файла (то есть если дескриптор задан как <em class='tag-i'>f: file</em>). В дескрипторе файла такого типа размер информации не указан. Но считается что файл состоит из байтов. Так вот этот параметр указывает, сколько байт можно прочесть либо записать в файл за один раз.<br>
<br>
Например: Если указать там цифру 10, то из нетипизированного файла командами чтения или записи будет читаться или записываться сразу по 10 байт. Меньше уже прочесть или записать за раз нельзя будет. Если нужно меньше - придется открывать файл заново. Если дескриптор файла является нетипизированным, и этот параметр не указан, то считается, что размер записи - 128 байт. Это значит, что читать или писать в этот файл можно только по 128 байт сразу. (Примечание: Для ТМТ паскаля размер записи если его не указывать будет 1 (один) байт. Хотя в справке указано 128. Это ошибка. Имейте в виду).<br>
<br>
Команда <strong class='tag-b'>rewrite</strong> Открывает файл связанный с указанным дескриптором. Если такого файла еще нет, то она создает его на носителе информации. После открытия она устанавливает позицию, в которой идет обработка данных в самое начало. То есть, после каждой команды <strong class='tag-b'>rewrite</strong> работа с информацией в файле будет идти с самого начала.<br>
<br>
Также (<span class="tag-color tag-color-named" data-value="red" style="color: red"><strong class='tag-b'>важно, запомните&#33;&#33;&#33;</strong></span>) эта команда напрочь удаляет любую информацию, которая была раннее в файле. То есть, если этот файл существовал в момент его открытия таким образом, то вся информация, которая в нем была, будет безжалостно стерта, и он станет пустым.<br>
<br>
Командой следует пользоваться для создания новых файлов, или если Вы хотите заново заполнить какой либо информацией старый файл.<br>
<br>
После открытия файла в файл можно записывать любую информацию. А так же ее читать (только если файл открыт как типизированный или нетипизированный (из текстовых файлов после открытия таким образом читать нельзя)). Вам может показаться абсурдной мысль о чтении информации из файла, открытого таким образом, Вы можете спросить: &quot;Как же можно читать информацию, если файл становится чистым и пустым, и в нём уже нет ничего?&quot;<br>
<br>
Я сразу вас успокою, и скажу, что далее мы рассмотрим перемещение (навигацию) по файлам, и дам ответ на этот вопрос. Кратко скажу, что можно к примеру записать в файл некоторый блок информации, затем вернуться назад, в какую либо часть этого блока, и прочитать или переписать часть этого блока (или весь блок) новой информацией.<br>
<br>
Следующая команда:<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Reset</span></strong><br>
Эта команда открывает файл, связанный с дескриптором, и позволяет читать или писать в него информацию (на запись устанавливаются ограничения - см. далее). Файл должен уже существовать. Иначе может возникнуть ошибка (подробнее об отслеживании существования файла читайте ниже).<br>
Синтаксис:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Reset(&#60;название_дескриптора_файла&#62;[, &#60;размер_записи&#62;]);</div></ol></div></div></div></div><br>
Как видите, полная аналогия с командой <strong class='tag-b'>rewrite</strong>. Скажу вам сразу, что тут не будет ничего нового, так как в любой команде открытия файлов в паскале будет именно такой формат.<br>
<br>
Те же параметры: <em class='tag-i'>&lt;название_дескриптора&gt;</em> - это дескриптор файла, который следует открыть для чтения.<br>
<em class='tag-i'>&lt;размер_записи&gt;</em> - это размер записи для файлов, чей дескриптор описан как <em class='tag-i'>File</em> (нетипизированный). Этот параметр подчиняется тем же правилам что и в команде <strong class='tag-b'>rewrite</strong>.<br>
Позиция в файле открытом таким образом будет установлена на начало файла.<br>
Поэтому если мы открыли файл этой командой, то начнем читать всю информацию с самого начала (об этом часто забывают на первых парах. Например если мы сначала открыли файл командой <strong class='tag-b'>reset</strong>, прочли часть информации, а затем переоткрыли его этой же командой, то мы при последующем чтении будем читать не информацию, идущую далее, а, опять же, с самого начала).<br>
Запись в файл, открытый таким образом можно производить только в том случае, если файл открыт как типизированный или нетипизированый. Записи в текстовый файл, открытый этой командой произвести <strong class='tag-b'>нельзя</strong>.<br>
<br>
Теперь на очереди еше одна команда:<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Append</span></strong><br>
Формат такой же как и у двух предыдущих команд с соблюдением всех правил и указаний.<br>
Открыв файл этой командой мы получаем возможность писать в него как и в команде <strong class='tag-b'>reset</strong>. Разница между ними в двух вещах: после открытия файла таким образом читать информацию из него нельзя (есть исключения, читай далее), и второе - последующая запись в файл будет писать информацию после уже существующей в нем. Ну если конечно файл был пустым, то команда будет работать аналогично <strong class='tag-b'>rewrite</strong> и <strong class='tag-b'>reset</strong>.<br>
<br>
В процессе тестирования я выяснил, что эта команда в Borland Pascal&#39;е к моему великому сожалению работает только с текстовыми файлами. Это значит что типизированные или нетипизированные файлы при помощи нее открыть нельзя. В отличие от этого паскаля компилятор ТМТ Pascal 3.9Lite позволяет открывать данной командой любой из трех типов файлов. Поэтому пользуясь компилятором ТМТ можно открыв файл таким образом производить как запись, так и чтение записей, перемещаясь по файлу (если файл не текстового типа) командой seek.<br>
<br>
Следует сказать, что файл должен существовать на носителе информации. В противном случае может возникнуть ошибка, а может и не возникнуть (читайте далее).<br>
<br>
Так-же есть команда, о которой я не могу не сказать, так как она очень тесно связана с открытием файлов.<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Truncate</span></strong><br>
Синтаксис:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Truncate(&#60;название_дескриптора_файла&#62;);</div></ol></div></div></div></div><br>
Ее нельзя вызывать для файлов, <strong class='tag-b'>не</strong> открытых ранее какой либо вышеописанной командой.<br>
Эта команда обрезает всю информацию в файле после текущей позиции. Например если мы находимся в середине файла, то все, что после того места где мы находимся будет удалено. И текущим положением в файле станет конец файла. Эта команда не работает на файлах, открытых как текстовые.<br>
<br>
Теперь поговорим об очень важных директивах: <strong class='tag-b'>{&#036;I+} и {&#036;I-}</strong><br>
Про директивы паскаля можно почитать тут: <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=40131' target='_blank'>Директивы транслятора BP7</a><br>
<br>
Эта директива включает или выключает автоматическую проверку ошибок ввода/вывода. Когда такая проверка включена, если возникает ошибка ввода/вывода, то выполнение программы завершается с сообщением о произошедшей ошибке. Но можно и отключить автоматическую проверку. И тогда на нас ляжет необходимость обрабатывать и корректировать соответствующие ошибки самим.<br>
<br>
Для чего нам это нужно? А очень просто. Типичной ошибкой ввода/вывода является то, что файл не найден. И если мы отключим автоматическое определение ошибок, то мы можем сами конкретно обработать вариант, когда файл, который мы пытаемся открыть не найден.<br>
<br>
Включить автоматическую проверку можно написав в коде программы так: {&#036;I+}. Отключить, соответственно, можно так: {&#036;I-}<br>
<br>
Если автоматическая проверка отключена, то результат операции ввода/вывода помещается в переменную <strong class='tag-b'>IOResult</strong> (Input/Output), которая имеет тип <strong class='tag-b'>Integer</strong>. Например при открытии файла туда помещается какое либо значение в зависимости от того, удалось ли открыть файл или нет.<br>
<br>
Если открытие произошло успешно, то в этой переменной будет находиться 0. Иначе в эту переменную будет записан код ошибки ввода/вывода, которая произошла. К сожалению я не нашел значений, и соответствующие им ошибки. Но нам этого и не нужно. Достаточно сравнить переменную <strong class='tag-b'>IOResult</strong> с нулем после попытки открыть файл, чтобы узнать, открылся ли файл, или нет.<br>
Вот пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; &nbsp;f:text;</div><div class="code_line">&nbsp;&nbsp; &nbsp;name:string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;write(&#39;Введите имя файла, который мы попытаемся открыть: &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;readln(name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ В данный момент если файла нет, то ошибки не произойдет. Ведь файл еще не пытались открыть }</div><div class="code_line">&nbsp;&nbsp; &nbsp;assign(f, myname);</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;{$I-} { - отключим стандартную проверку ошибок ввода/вывода}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;reset(f); &nbsp; {попробуем открыть файл}</div><div class="code_line">&nbsp;&nbsp; &nbsp;{$I+}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ioresult = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;writeln(&#39;Все в порядке. Файл нашелся и открылся нормально&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;else writeln(&#39;Файл с именем &#39;,myname,&#39; не найден. Попробуйте другое имя&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;... {ну тут остальные действия. Какие - читайте далее}</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green">Как следует вникните в этот код. Продумайте все вышесказанное. Возможно вам следует сделать перерыв. Так как дальнейшая часть хоть и самая интересная, но не менее сложная. И возможно вам следует укрепить все что Вы прочли в сознании. Я по собственному опыту знаю, что большое количество сложной информации доходит до подсознания не сразу. Поэтому лучше сделайте перерыв. Поэкспериментируйте с тем, что прочли выше. Это будет полезным опытом, ведь я мог что-либо забыть сказать.</span>]]></description>
        <author>Some1</author>
        <category>Pascal: Файлы и записи</category>
      </item>
	
      </channel>
      </rss>
	