понедельник, 25 марта 2013 г.

Ввод/вывод. Стандартные подпрограммы

Перевод раздела Standard Routines and Input-Output из справочной системы Delphi


В этой теме обсуждается текстовый и файловый ввод/вывод, приводится обзор списка функций стандартных библиотек. Большая часть перечисленных здесь процедур и функций объявлена в модулях System и SysInit, которые автоматически подключаются во всех приложениях. Другие функции встроены в компилятор и обрабатываются так, как будто они присутствуют в модуле System.

Некоторые стандартные подпрограммы включены в такие модули как SysUtils, и для доступа к ним из ваших программ необходимо включить имена модулей в раздел uses. Вы не должны ни включать модуль System в раздел uses, ни изменять его программный код или пытаться перекомпилировать его.



Замечание. Для новых программ вы возможно захотите использовать классы и функции для работы с файлами, которые объявлены в модулях System.Classes и System.SysUtils. Для работы с файлами в Delphi на текущий момент рекомендуется использовать Класс Classes.TStream и его предков (чтобы получить информацию по их подпрограммам см. Streams, Reader and Writers). Для работы с текстовыми файлами рекомендуется использовать TStreamReader и TStreamWriter, а не Write и Writeln. API Categories Index содержит список подпрограмм и классов по этим вопросам.

Замечание. BlockRead и BlockWrite имеют нетипизированные параметры, которые могут явиться причиной ошибок в работе с памятью. Оба метода зависят от размера записи, установленном неявно при предыдущем вызове Reset или Rewrite. Применение потоков дает программисту более высокий уровень гибкости и функциональности.




Работа с файлами

Далее в таблице перечислены подпрограммы ввода/вывода.

Процедура или функцияОписание
Append Открывает существующий файл для добавления.
AssignFile Связывает имя внешнего файла с файловой переменной
BlockRead Читает одну или несколько записей из нетипизированного файла.
BlockWrite Записывает одну или несколько записей в нетипизированный файл.
ChDir Изменяет текущий директорий.
CloseFile Закрывает открытый файл.
Eof Возвращает признак конца файла.
Eoln Возвращает признак конца строки текстового файла.
Erase Стирает внешний файл.
FilePos Возвращает текущую позицию в нетипизированном файле.
FileSize Возвращает текущий размер файла. Не применяется с текстовыми файлами.
Flush Очищает буфер при записи текстового файла.
GetDir Возвращает текущий директорий на определенном диске.
IOResult Возвращает целочисленное значение, которое является статусом последней выполненной операции ввода/вывода.
MkDir Создает вложенный директорий.
Read Считывает одно или несколько значений из файла в одну или несколько переменных.
Readln Делает тоже самое, что и Read, затем переходит к началу следующей строки в текстовом файле.
Rename Переименовывает внешний файл.
Reset Открывает существующий файл.
Rewrite Создает и открывает новый файл.
RmDir Удаляет пустой поддиректорий.
Seek Перемещает текущую позицию в типизированном или нетипизированном файле определенное место. Не используется с текстовыми файлами.
SeekEof Возвращает признак конца файла в текстовом файле.
SeekEoln Возвращает признак конца строки в текстовом файле.
SetTextBuf Связывает буфер ввода/вывода с текстовым файлом.
Truncate Обрезает типизированный или нетипизированный файл до текущей позиции.
Write Записывает одно или несколько значений в файл.
Writeln Делает тоже самое, что и Write, затем записывает маркер конца строки в текстовый файл.

Файловая переменная – это переменная типа файл. Есть три вида файлов: типизированные, текстовые и нетипизированные. Синтаксис объявления файловых типов дан в разделе Файловые типы. Следует помнить, что файловые типы доступны только при работе с платформой Win32.

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

После того как связь с внешним файлом установлена, для подготовки ввода/вывода файловая переменная должна быть открыта. Существующий файл может быть открыт процедурой Reset, а новый файл создается и открывается процедурой Rewrite. Текстовые файлы, открытые при помощи Reset, доступны только для чтения. Текстовые файлы, открытые при помощи Rewrite и Append, доступны только для записи. Типизированные и нетипизированные файлы допускают и чтение, и запись, вне зависимости от того, были ли они открыты Reset или Rewrite.

Все файлы представляют собой линейную последовательность компонентов, каждый из которых имеет тип (тип компонента или тип запись), соответствующий типу файла. Компоненты пронумерованы, отсчет начинается с нуля.

Обычно доступ к содержимому файлов осуществляется последовательно. То есть, после того как компонент считан процедурой Read или записан процедурой Write, указатель текущей позиции в файле перемещается к следующему компоненту. Доступ к типизированным и нетипизированным файлам может также выполняться в произвольном порядке при помощи процедуры Seek, перемещающей указатель текущей позиции к указанному компоненту. Стандартные функции FilePos и FileSize используются для определения текущей позиции и текущего размера файла.

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

По умолчанию все вызовы стандартных процедур и функций ввода/вывода автоматически проверяются на ошибки, и при возникновении ошибки инициируется исключение (или работа программы завершается, если не включен режим обработки исключений). Эта автоматическая проверка может быть включена или выключена при помощи директив компилятора {$I+} и {$I-}. Когда проверка ввода/вывода выключена, то есть программа или функция компилируется в режиме {$I-}, ошибка ввода/вывода не приводит к инициированию исключения, а для проверки результата операции ввода/вывода вам необходимо вызвать стандартную функцию IOResult.

Вам необходимо вызывать функцию IOResult для очистки ошибки, даже если вам не нужна информация о ней. Если очистки ошибки не происходит и текущим режимом является {$I-}, следующий вызов функций ввода/вывода завершается предыдущей ошибкой IOResult.



Текстовые файлы

В этом разделе обобщается информация по вводу/выводу с использованием файловых переменных стандартного типа Text.

При открытии текстового файла, внешний файл интерпретируется особым образом: он рассматривается как последовательность символов, отформатированных в строки, каждая из которых завершается маркером конца строки (символ возврата каретки, за которым может следовать символ перевода строки). Тип текст отличается от типа file of Char.

Для текстовых файлов существуют специальные формы процедур Read и Write, которые позволяют считывать значения, не являющиеся символьным типом. Такие значения автоматически интерпретируются в их символьном представлении. Например, инструкция Read(F, I)(где I – это целочисленная переменная) считывает последовательность цифр, интерпретирует эту последовательность как десятичное число и сохраняет его в  I.

Существует две стандартные переменные типа текстовый файл - System.Input и System.Output . Стандартная переменная System.Input – это файл только для чтения, связанный со стандартным устройством ввода операционной системы (обычно это клавиатура). Стандартная файловая переменная System.Output – это файл только для записи, связанный со стандартным устройством вывода операционной системы (обычно это дисплей). Перед началом выполнения приложения System.Input и System.Output открываются в автоматическом режиме, как при выполнении следующих инструкций:

AssignFile(Input, '');
Reset(Input);
AssignFile(Output, '');
Rewrite(Output);

Замечание: Для приложений Win32 тексто-ориентированный ввод/вывод возможен только в консольных приложениях, то есть приложениях, скомпилированных с опцией Generate console application на странице Linking в диалоговом окне опций проекта или с опцией командной строки компилятора -cc. В приложениях графического пользовательского интерфейса (не консольных) любая попытка чтения или записи при помощи System.Input или System.Output вызовет ошибку ввода/вывода.

Некоторые стандартные подпрограммы ввода/вывода, работающие с текстовыми файлами, не нуждаются в явном указании файловой переменной в качестве параметра. Если файловый параметр опущен, System.Input или System.Output принимаются за умолчание, в зависимости от того, ориентирована подпрограмма на ввод или вывод. Например, вызов Read(X)соответствует Read(Input, X), а Write(X) – соответствует вызову Write(Output, X).

Если при вызове подпрограмм ввода/вывода, работающих с текстовыми файлами, вы указываете файл, он должен быть связан с внешним файлом при помощи AssignFile и открыт при помощи Reset, Rewrite или Append. При передаче в подпрограмму вывода параметра-файла, открытого при помощи Reset, происходит ошибка. Ошибка случится также, если вы передаете в подпрограмму ввода файл, открытый при помощи Rewrite или Append.



Нетипизированные файлы

Нетипизированные файлы представляют собой низкоуровневые каналы ввода/вывода, которые чаще всего используют для прямого доступа к файлам на диске без учета их типа и структуры. Нетипизированные файлы объявляются при помощи ключевого слова file. Например:

varDataFile: file;

При работе с нетипизированными файлам в процедурах Reset и Rewrite разрешается указывать дополнительный параметр для определения размера записи, используемого при передаче данных. По историческим причинам размер записи по умолчанию равен 128 байтам. Размер записи равный 1 – это единственное значение, которое правильно отражает размерность любого файла (поскольку в этом случае нельзя прочитать запись частично).

При работе с нетипизированными файлами разрешен вызов любых стандартных подпрограмм, кроме Read и Write. Вместо них следует использовать две процедуры - BlockRead и BlockWrite, который применяются для высокоскоростной передаче данных.



Драйверы устройств для текстовых файлов

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

Драйвер устройства определяют четыре функции:Open, InOut, Flush и Close. Заголовок функции для каждой из них выглядит следующим образом:

function DeviceFunc(var F: TTextRec): Integer;

где DeviceFunc – это название функции (то есть Open, InOut, Flush или Close). Значением, которое возвращают эти функции, становится результат, возвращаемый IOResult. Операция выполнена успешно, если возвращаемое значение равно нулю.

Чтобы связать функции интерфейса драйвера с определенным файлом, вам необходимо переписать процедуру Assign. Процедура Assign должна назначить адреса четырех функций интерфейса устройства четырем указателям на функции в переменной текстового файла. Кроме того она должна записать волшебную константу fmClosed в поле Mode, записать размер буфера текстового файла в BufSize,записать указатель на буфер текстового файла вBufPtr и очистить строку Name.

Для примера предположим, что четыре функции интерфейса драйвера называются DevOpen, DevInOut, DevFlush и DevClose, процедура Assign могла бы выглядеть следующим образом:

procedure AssignDev(var F: Text);
begin 
  with TTextRec(F) do
    begin    
      Mode := fmClosed;    
   BufSize := SizeOf(Buffer);    
   BufPtr := @Buffer;    
   OpenFunc := @DevOpen;    
   InOutFunc := @DevInOut;    
   FlushFunc := @DevFlush;    
   CloseFunc := @DevClose;    
   Name[0] := #0;   
 end;
end;

Функции интерфейса устройства могут использовать поле UserData в записи файла для хранения частной информации. Это поле никогда не изменяется файловой системой продукта.



Функция Open

Функция Open вызывается стандартными процедурами  Reset, Rewrite и Append для открытия текстового файла, связанного с устройством. При запуске функции константы поля Mode fmInput, fmOutput или fmInOut определяют, была ли функция Open вызвана из Reset, Rewrite или из Append.

В зависимости от значения Mode функция Open подготавливает файл для ввода или вывода. Если Mode имеет значение fmInOut (это означает, что вызов был выполнен из Append), то до завершения работы функции Open оно должно быть установлено в fmOutput.

Функция Open всегда вызывается перед запуском остальных функций интерфейса устройства. Поэтому  AssignDev только инициализирует поле  OpenFunc, откладывая инициализацию остальных векторов до выполнения Open. После этого, в зависимости от значения Mode, функция Open устанавливает указатели либо на функции ввода, либо на функции ввода. По этой причине в подпрограммах InOut, Flush и CloseFile нет необходимости определять текущий режим работы.



Функция InOut

Функция InOut вызывается стандартными подпрограммами Read, Readln, Write, Writeln, Eof, Eoln, SeekEof, SeekEoln и CloseFile в случае, когда необходим ввод или вывод из устройства.

Когда значение Mode установлено в fmInput, функция InOut считывает символы в количестве, определяемом BufSize, в BufPtr^, и возвращает количество считанных символов в BufEnd. Кроме того, она записывает в BufPos значение 0. Если в результате запроса ввода функция InOut возвращает 0 в BufEnd, Eof для этого файла становится равным True.

Когда Mode имеет значение fmOutput, функция InOut записывает символы изBufPtr^, количество которых определяется значением BufPos,  и затем возвращает 0 в BufPos.



Функция function

Функция Flush вызывается при завершении каждого вызова Read, Readln, Write и Writeln. Опционально она может очищать буфер текстового файла.

Если значение Mode установлено в fmInput, функция Flush может сохранить значение 0 в BufPos и BufEnd чтобы удалить оставшиеся (непрочитанные) символы из буфера, однако эта функциональность используется редко.

Если Mode имеет значение fmOutput, функция Flush может заполнить содержимое буфера так же, как это происходит при вызове функции InOut, это позволяет быть уверенным, что текст, записываемый в устройство, появится там немедленно. Если Flush не выполнит никаких действий, текст не появится в устройстве до момента заполнения буфера или закрытия файла.



Функция Close

Функция Close вызывается стандартной процедурой CloseFile для закрытия текстового файла, связанного с устройством. (Процедуры Reset, Rewrite и Append тоже вызывают Close, в том случае, когда файл, который они открывают, уже открыт.) Если Mode имеет значение fmOutput, перед вызовом Close, файловая система вызывает функцию InOut чтобы гарантировать, что все символы записаны в устройство.



Обработка строк, завершающихся нулевым символом

Расширенный синтаксис языка Delphi позволяет стандартным процедурам Read, Readln, Str и Val работать с индексируемыми от нуля массивами символов, а стандартным процедурам Write, Writeln, Val, AssignFile и Rename работать как индексируемыми от нуля символьными массивами, так и с символьными указателями.



Функции для работы со строками, завершающимися нулевым символом

Следующие функции предназначены для обработки строк, завершающихся нулевым символом.

ФункцияОписание
StrAlloc Создает символьный буфер заданного размера в куче.
StrBufSize Возвращает размер символьного буфера, созданного при помощи StrAlloc или StrNew.
StrCat Сцепляет две строки.
StrComp Сравнивает две строки.
StrCopy Копирует строку.
StrDispose Ликвидирует символьный буфер, созданный при помощи StrAlloc или StrNew.
StrECopy Копирует строку и возвращает указатель на конец строки.
StrEnd Возвращает указатель на конец строки.
StrFmt Форматирует одно или несколько значений в строку.
StrIComp Сравнивает две строки без учета регистра символов.
StrLCat Сцепляет две строки в строку с заданной максимально длиной.
StrLComp Сравнивает две строки по фрагменту заданной длины.
StrLCopy Копирует часть строки заданного размера.
StrLen Возвращает длину строки.
StrLFmt Форматирует одно или несколько значений в строку заданного размера.
StrLIComp Сравнивает две строки по фрагменту заданной длины без учета регистра символов.
StrLower Преобразует символы в строке в строчные (нижний регистр).
StrMove Перемещает символы из одной строки в другую.
StrNew Создает строку в куче.
StrPCopy Копирует паскалевскую строку в строку, завершающуюся нулевым символом.
StrPLCopy Копирует фрагмент паскалевской строки заданного размера в строку, завершающуюся нулевым символом.
StrPos Возвращает указатель на первое вхождение заданной подстроки в строке.
StrRscan Возвращает указатель на последнее вхождение заданного символа в строке.
StrScan Возвращает указатель на первое вхождение заданного символа в строке.
StrUpper Преобразует символы в строке в верхний регистр.

У стандартных функций для обработки строк есть мультибайтовые коллеги, поддерживающие и работу с символами, специфичными для локали. Названия мультибайтовых функций начинаются с префикса Ansi-. Например, мультибайтовая версия StrPos – это AnsiStrPos. Поддержка мультибайтовых символов зависит от операционной системы и основывается на текущей локали.



Динамические строки

Модуль System содержит три функции (WideCharToString, WideCharLenToString и StringToWideChar), которые могут быть использованы для преобразования динамических строк, завершающихся нулевым символом в строки с однобайтовой и двухбайтовой длиной.

Присваивание будет также выполнять преобразование строк. То есть оба следующих примера являются правильными:

MyAnsiString := MyWideString;
MyWideString := MyAnsiString;


Прочие стандартные подпрограммы

Ниже в таблице указаны часто используемые процедуры и функции, которые можно найти в библиотеках, поставляемых с продуктом. Этот перечень стандартных подпрограмм не является полным.

Процедура или функция Описание
Addr Возвращает указатель на заданный объект.
AllocMem Выделяет блок памяти и инициализирует его байты нолями.
ArcTan Вычисляет арктангенс заданного числа.
Assert Создает исключительную ситуацию, если значение передаваемого как параметр выражения не является истиной.
Assigned Проверяет значение указателя или процедурной переменной на nil.
Beep Подает стандартный сигнал.
Break Выполняет выход из инструкций for, while, или repeat.
ByteToCharIndex Возвращает позицию символа, содержащего определенный байт, в строке.
Chr Возвращает символ для заданного целочисленного значения.
Close Закрывает файл.
CompareMem Выполняет бинарное сравнение двух фрагментов памяти.
CompareStr Сравнивает строки с учетом регистра.
CompareText Сравнивает строки по порядковым значениям символов без учета регистра.
Continue Начинает новую итерацию в инструкциях for, while или repeat.
Copy Возвращает подстроку из строки или сегмента динамического массива.
Cos Вычисляет косинус угла.
CurrToStr Преобразует значение типа currency в строку.
Date Возвращает текущую дату.
DateTimeToStr Преобразует переменную типа TDateTime в строку.
DateToStr Преобразует значение типа TDateTime в строку.
Dec Уменьшает значение переменной порядкового типа или значение типизированного указателя.
Dispose Освобождает динамически выделенную память переменной.
ExceptAddr Возвращает адрес, по которому возникла текущая исключительная ситуация.
Exit Выполняет выход из текущей процедуры.
Exp Вычисляет экспоненту X.
FillChar Заполняет смежные байты заданным значением.
Finalize Финализирует динамически созданную переменную.
FloatToStr Преобразует число с плавающей точкой в строку.
FloatToStrF Преобразует число с плавающей точкой в строку с использованием заданного форматирования.
FmtLoadStr Возвращает отформатированную строку, полученную из ресурсов программы.
FmtStr Собирает форматированную строку из массива аргументов.
Format Собирает форматированную строку из массива аргументов.
FormatDateTime Форматирует значение типа TDateTime.
FormatFloat Форматирует число с плавающей точкой.
FreeMem Освобождает выделенную память.
GetMem Выделяет динамическую память и возвращает указатель на выделенную
Halt Инициирует аварийное завершение работы программы.
Hi Возвращает старший байт выражения как положительное целое число.
High Возвращает верхнюю границу перечисляемого типа, массива или строки.
Inc Увеличивает значение переменной перечисляемого типа или типизированного указателя.
Initialize Инициализирует динамическую переменную.
Insert Вставляет подстроку в указанную позицию в строке.
Int Возвращает целочисленную часть дробного числа.
IntToStr Преобразует целое число в строку.
Length Возвращает длину строки или массива.
Lo Возвращает младший байт выражения как положительное целое число.
Low Возвращает верхнюю границу перечисляемого типа, массива или строки.
Lowercase Преобразует строку ASCII в нижний регистр.
MaxIntValue Возвращает максимальное значение в массиве целых чисел.
MaxValue Возвращает максимальное значение в массиве.
MinIntValue Возвращает минимальное значение в массиве целых чисел.
MinValue Возвращает максимальное значение в массиве.
New Создает динамическую переменную и связывает с ней указатель.
Now Возвращает текущую дату и время.
Ord Возвращает порядок значения перечисляемого типа.
Pos Возвращает позицию первого вхождения однобайтового символа указанной подстроки в строке.
Pred Возвращает значение, предшествующее заданному порядковому значению.
Ptr Преобразует значение в указатель.
Random Генерирует случайные числа в заданном диапазоне.
ReallocMem Reallocates a dynamically allocatable memory.
Round Возвращает значение дробного числа, округленное до ближайшего целого.
SetLength Устанавливает длину строки или динамического массива.
SetString Задает содержимое строки и ее длину.
ShowException Выводит сообщение об исключении и его адрес.
ShowMessage Выводит окно с неформатированным сообщением и кнопкой ОК.
ShowMessageFmt Выводит окно с форматированным сообщением и кнопкой ОК.
sin Возвращает синус угла в радианах.
SizeOf Возвращает количество байт, требуемое для хранения переменной или типа.
Slice Возвращает фрагмент массива.
Sqr Возвращает число, возведенное в квадрат.
Sqrt Возвращает квадратный корень числа.
Str Преобразует целое или дробное число в строку.
StrToCurr Преобразует строку в значение типа currency.
StrToDate Преобразует строку в дату формата TDateTime.
StrToDateTime Преобразует строку в дату и время (TDateTime).
StrToFloat Преобразует строку в число с плавающей точкой.
StrToInt Преобразует строку в целое число.
StrToTime Преобразует строку во время (TDateTime).
StrUpper Возвращает строку ASCII в верхнем регистре.
Succ Возвращает значение, следующее за заданным порядковым значением.
Sum Возвращает сумму элементов массива.
Time Возвращает текущее время.
TimeToStr Преобразует значение типа TDateTime в строку.
Trunc Обрезает вещественное число до целого.
UniqueString Обеспечивает уникальность ссылки на строку. (Строка может быть скопирована с уникальной ссылкой).
Upcase Преобразует символ в верхний регистр.
UpperCase Возвращает строку в верхнем регистре.
VarArrayCreate Создает массив значений типа variant.
VarArrayDimCount Возвращает количество измерений массива значений типа variant.
VarArrayHighBound Возвращает верхнюю границу измерения в массиве значений типа variant.
VarArrayLock Блокирует массив значений типа variant и возвращает указатель на данные.
VarArrayLowBound Возвращает нижнюю границу измерения в массиве значений типа variant.
VarArrayOf Создает и заполняет одномерный массив вариантов.
VarArrayRedim Изменяет размер массива вариантов.
VarArrayRef Возвращает ссылку на массив вариантов.
VarArrayUnlock Разблокирует массив вариантов.
VarAsType Преобразует значение типа variant в заданный тип.
VarCast Преобразует значение типа variant в заданный тип, сохраняя результат в переменной.
VarClear Очищает значение типа variant.
VarCopy Копирует значение типа variant.
VarToStr Преобразует значение типа variant в строку.
VarType Возвращает код типа для заданного значения типа variant.

Комментариев нет:

Отправить комментарий