В этой теме обсуждается текстовый и файловый ввод/вывод, приводится обзор списка функций стандартных библиотек. Большая часть перечисленных здесь процедур и функций объявлена в модулях 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. |