SeekEof — Функция Delphi

Содержание

SeekEof — Функция Delphi

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

Итак, для выполнения операции чтения или записи необходимо произвести следующие действия:

1. Объявить файловую переменную необходимого типа.

2. При помощи функции AssignFile связать эту переменную с требуемым файлом.

3. Открыть файл при помощи функций Append, Reset, Rewrite.

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

5. Закрыть файл при помощи функции CloseFile .

По сравнению с Turbo Pascal изменились названия только двух функций: Assign стала AssignFile , a Close превратилась в CloseFile .

В качестве примера рассмотрим небольшой фрагмент исходного кода.

then AssignFiie(F, OpenDlg.FileName)

else Exit; Reset(F);

while Not EOF(F) do

Если в диалоге открытия файла OpenDlg был выбран файл, то его имя связывается с файловой переменной F при помощи процедуры AssignFiie . В качестве имени файла рекомендуется всегда передавать полное имя файла (включая его маршрут). Как раз в таком виде возвращают результат выбора файла диалоги работы с файлами TOpenDialog, TOpenPictureDiaiog . Затем при помощи процедуры Reset этот файл открывается для чтения и записи.

В цикле выполняется чтение из файла текстовых строк и запись их в компонент TMemo . Процедура Readin осуществляет чтение текущей строки файла и переходит на следующую строку. Цикл выполняется, пока функция EOF не сообщит о достижении конца файла.

После завершения чтения файл закрывается.

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

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

Открытие файла может осуществляться тремя процедурами — в зависимости от типа его дальнейшего использования.

procedure Reset(var F: File [; RecSize: Word ]);

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

открывает файл для записи информации после его последней строки, текущая позиция устанавливается на конец файла.

procedure Rewrite(var F: File [; RecSize: Word ]);

создает новый файл и открывает его, текущая позиция устанавливается в начало файла. Если файл с таким именем уже существует, то он перезаписывается.

Переменная RecSize используется только при работе с нетипизированными файлами и определяет размер одной записи для операции передачи данных. Если этот параметр опущен, то по умолчанию RecSize равно 128 байт.

Чтение данных из типизированных и текстовых файлов выполняют процедуры Read И Readin.

Процедура Read имеет различное объявление для текстовых и других типизированных файлов:

  • procedure Read([var F: Text;] VI [, V2. Vn]);
  • procedure Read(F, VI [, V2. Vn]);

для других типизированных файлов.

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

procedure Readln([ var F: Text; ] VI [, V2. Vn ]);

считывает одну строку текстового файла и устанавливает текущую позицию на следующей строке. Если использовать процедуру без переменных vi. .vn, то она просто передвигает текущую позицию на очередную строку файла.

Процедуры для записи в файл write и writein описаны аналогично:

procedure Write([var F: Text; ] PI [, P2. Pn]) ; procedure Writein([ var F: Text; ] PI [, P2. Pn ]);

Параметры P1, P2, . Pn могут быть одним из целых или вещественных типов, одним из строковых типов или логическим типом. Но у них есть возможность дополнительного форматирования при выводе. Каждый параметр записи может иметь форму:

Р n — выводимая переменная или выражение;

MinWidth — минимальная ширина поля в символах, которая должна быть больше 0;

DecPlaces — содержит количество десятичных символов после запятой при отображении вещественных чисел с фиксированной точкой.

Обратите внимание, что для текстовых файлов в функциях Read и write файловая переменная F может быть опущена. В этом случае чтение и запись осуществляются в стандартные файлы ввода/вывода. Когда программа компилируется как консольное приложение (флаг <$APPTYPE CONSOLE>), Delphi автоматически связывает входной и выходной файлы с окном консоли.

Для контроля за текущей позицией в файле применяются две основные функции. Функция EOF (F) возвращает значение True , если достигнут конец файла. Функция EOLN(F) аналогично сигнализирует о достижении конца строки. Естественно, в качестве параметра в функции необходимо передавать файловую переменную.

обеспечивает смещение текущей позиции на N элементов. Размер одного элемента в байтах зависит от типа данных файла (от типизированной переменной).

Рассмотрим теперь режим блочного ввода/вывода данных между файлом и областью адресного пространства (буфером). Этот режим отличается значительной скоростью передачи данных, причем скорость пропорциональна размеру одного передаваемого блока — чем больше блок, тем больше скорость.

Для реализации этого режима необходимо использовать только нетипизированные файловые переменные. Размер блока определяется в процедуре открытия файла ( Reset, Rewrite ). Непосредственно для выполнения операций используются процедуры BlockRead и BlockWrite .

procedure BlockRead(var F: File; var Buf; Count: Integer

[; var AmtTransferred: Integer]);

выполняет запись блока из файла в буфер. Параметр F ссылается на нетипизированную файловую переменную, связанную с нужным файлом.

Параметр Buf определяет любую переменную (число, строку, массив, структуру), в которую читаются байты из файла. Параметр Count содержит число считываемых блоков. Наконец, необязательный параметр AmtTransferred возвращает число реально считанных блоков.

При использовании блочного чтения или записи размер блока необходимо выбирать таким образом, чтобы он был кратен размеру одного значения того типа, который хранится в файле. Например, если в файле хранятся значения типа Double (8 байт), то размер блока может быть равен 8, 16, 24, 32 и т. д. Фрагмент исходного кода блочного чтения при этом выглядит следующим образом:

DoubleArray: array [0..255] of Double;

if OpenDlg.Execute then AssignFile(F, OpenDlg.FileName) else Exit;

BlockRead(F, DoubleArray, 32, Transferee!);

ShowMessage(‘Считано ‘+IntToStr(Transfered)+’ блоков’);

Как видно из примера, размер блока установлен в процедуре Reset и кратен размеру элемента массива DoubleArray , в который считываются данные. В переменной Transfered возвращается число считанных блоков. Если размер файла меньше заданного в процедуре BlockRead числа блоков, ошибка не возникает, а в переменной Transfered передается число реально считанных блоков.

procedure BlockWrite(var f: File; var Buf; Count: Integer

[; var AmtTransferred: Integer]);

Оставшиеся функции ввода/вывода, работающие с файловыми переменными, подробно описаны в табл. 9.1.

Таблица 9.1. Процедуры и функции для работы с файлом

function ChangeFileExt (const FileName, Extension: string): string;

Функция позволяет изменить расширение файла. При этом сам файл не переименовывается

procedure ChDir(S: string);

Процедура изменяет текущий каталог на другой, путь к которому описан в строке s

procedure CloseFile (var F) ;

Вызов процедуры разрывает связь между файловой переменной и файлом на диске.

Имя этой процедуры изменено из-за конфликта имен в Delphi (в Borland Pascal используется процедура Close )

function DeleteFile (const FileName: string): Boolean;

Функция производит удаление файла FileName с диска и возвращает значение False , если файл удалить не удалось или файл не существует

function ExtractFileExt (const FileName: string): string;

Функция возвращает расширение файла

function ExtractFileName (const FileName: string) : string;

Извлекает имя и расширение файла, содержащегося в параметре FileName

function ExtractFilePath( const FileName: string): string;

Функция возвращает полный путь к файлу

procedure Erase (var F);

Удаляет файл, связанный с файловой переменной F

function FileSearch (const Name, DirList: string) : string;

Данная процедура производит поиск в каталогах DirList файла Name . Если в процессе выполнения FileSearch обнаруживается искомое имя файла, то функция возвращает в строке типа string полный путь к найденному файлу. Если файл не найден, то возвращается пустая строка

function FileSetAttr (const FileName: string; Attr: Integer): Integer;

Присваивает файлу с именем FileName атрибуты Attr. Функция возвращает 0, если присвоение атрибутов прошло успешно. В противном случае возвращается код ошибки

function FilePos (var F): Longint;

Возвращает текущую позицию файла. Функция используется для нетекстовых файлов. Перед вызовом FilePos файл должен быть открыт

function FileSize (var F): Integer;

FileSize возвращает размер файла в байтах или количество записей в файле, содержащем записи. Перед вызовом данной функции файл должен быть открыт.

Для текстовых файлов функция FileSize не используется

procedure Flush (var F: Text);

Процедура очищает буфер текстового файла, открытого для записи. F— файловая переменная.

Когда текстовый файл открыт для записи с использованием функции Rewrite или Append, Flush очищает выходной буфер, связанный с файлом. После выполнения данной процедуры все символы, которые направлены для записи в файл, будут гарантированно записаны в нем

procedure GetDir(D: Byte; var S: string);

Возвращает число, соответствующее диску, на котором содержится текущий каталог s. о может принимать одно из следующих значений:

0 — по умолчанию (текущий);

Процедура не генерирует код ошибки. Если имя диска в D оказывается ошибочным, то в строке S возвращается значение Х:\, как если бы текущая папка была на этом ошибочно указанном диске

function lOResult: Integer;

Функция возвращает статус последней произведенной операции ввода/вывода, если контроль ошибок выключен

procedure MkDir(S: string);

Процедура создает новый каталог, который описывается в строке S

procedure Rename (var F; NewName: string) ;

Процедура изменяет имя файла, связанного с файловой переменной F. Переменная NewName является строкой типа string или PChar (если включена поддержка расширенного синтаксиса)

procedure RmDir(S: string);

Процедура удаляет пустой каталог, путь к которому задается в строке S. Если указанный каталог не существует или он не пустой, то возникает сообщение об ошибке ввода/вывода

procedure Seek (var F; N: Longint) ;

Перемещает текущую позицию курсора на N позиций. Данная процедура используется только для открытых типизированных или нетипизированных файлов для проведения чтения/записи с нужной позиции файла. Началу файла соответствует нулевой номер позиции. Для добавления новой информации в конец существующего файла необходимо установить указатель на символ, следующий за последним. Для этого можно использовать выражение Seek (F, FileSize(F))

function SeekEof[(var F: Text) ] : Boolean;

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

function SeekEoln[ (var F: Text) ] : Boolean;

Возвращает значение True , если указатель текущей позиции находится на символе конца строки.

SeekEoln может быть использован только с открытым текстовым файлом

procedure SetTextBuf (var F: Text; var Buf [; Size: Integer] );

Связывает с текстовым файлом буфер ввода/вывода. F — файловая переменная текстового типа. Каждая файловая переменная текстового типа имеет внутренний буфер емкостью 128 байт, в котором накапливаются данные при чтении и записи. Такой буфер пригоден для большинства операций. Однако при выполнении программ с интенсивным вводом/выводом буфер может переполниться, что приведет к записи операций ввода/вывода на диск и, как следствие, к существенному замедлению работы приложения. SetTextBuf позволяет помещать в текстовый файл F информацию об операциях ввода/вывода вместо ее размещения в буфере. Size указывает размер буфера в байтах. Если этот параметр опускается, то полагается размер, равный SizeOf (Buf). Новый буфер действует до тех пор, пока F не будет связана с новым файлом процедурой AssignFile

Удаляет все позиции, следующие после текущей позиции в файле. А текущая позиция становится концом файла. С переменной F может быть связан файл любого типа за исключением текстового

Вещество и поле не есть что-то отдельное от эфира, также как и человеческое тело не есть что-то отдельное от атомов и молекул его составляющих. Оно и есть эти атомы и молекулы, собранные в определенном порядке. Также и вещество не есть что-то отдельное от элементарных частиц, а оно состоит из них как базовой материи. Также и элементарные частицы состоят из частиц эфира как базовой материи нижнего уровня. Таким образом, всё, что есть во вселенной — это есть эфир. Эфира 100%. Из него состоят элементарные частицы, а из них всё остальное. Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМА
Рыцари теории эфира
01.10.2020 — 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]69vJGqDENq4[/Youtube][/center]
[center]14:36[/center]
Osievskii Global News
29 сент. Отправлено 05:20, 01.10.2020 г.’ target=_top>Просвещение от Вячеслава Осиевского — Карим_Хайдаров.
30.09.2020 — 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Ok]376309070[/Ok][/center]
[center]11:03[/center] Отправлено 12:51, 30.09.2020 г.’ target=_top>Просвещение от Дэйвида Дюка — Карим_Хайдаров.
30.09.2020 — 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]VVQv1EzDTtY[/Youtube][/center]
[center]10:43[/center]

интервью Раввина Борода https://cursorinfo.co.il/all-news/rav.
мой телеграмм https://t.me/peshekhonovandrei
мой твиттер https://twitter.com/Andrey54708595
мой инстаграм https://www.instagram.com/andreipeshekhonow/

[b]Мой комментарий:
Андрей спрашивает: Краснодарская синагога — это что, военный объект?
— Да, военный, потому что имеет разрешение от Росатома на манипуляции с радиоактивными веществами, а также иными веществами, опасными в отношении массового поражения. Именно это было выявлено группой краснодарцев во главе с Мариной Мелиховой.

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

SeekEOF

Set file position to end of file

Declaration

Source position: systemh.inc line 1256

function SeekEOF : Boolean ;

Description

SeekEof returns True is the file-pointer is at the end of the file. It ignores all whitespace. Calling this function has the effect that the file-position is advanced until the first non-whitespace character or the end-of-file marker is reached.

If the end-of-file marker is reached, True is returned. Otherwise, False is returned.

If the parameter F is omitted, standard Input is assumed.

Remark: The SeekEOF function can only be used on real textfiles: when assigning the file to other kinds of (virtual) text files, the function may fail, although it will perform a number of tests to guard against wrong usage.

Errors

A run-time error is generated if the file F isn’t opened.

Использование процедур и функций в Delphi

Скобки

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

Возможность перегрузки

Впервые концепция перегрузки процедур и функций была реализована в Delphi 4. Она позволяет иметь несколько различных процедур и функций с одинаковыми именами, но с разными списками параметров. Такие процедуры и функции должны быть описаны с применением директивы overload.

procedure Test (I: integer); overload;
procedure Test (S: string); overload;
procedure Test (D: double); overload;

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

Передача параметров

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

Передача параметров по значению

Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно). Этот способ передачи является у большинства самым излюбленным, но в тоже время является и самым не практичным, т.к. для выполнения метода выделяется дополнительная память для создания точной копией передаваемой переменой. Для решения этой проблемы следует использовать один из способов описанных ниже.

Передача параметров по ссылке

Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

procedure ChangeMe(var x: longint);
begin
x := 2; // Параметр х изменен вызванной процедурой
end;

Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

Передача параметров констант

Если нет необходимости изменять передаваемые функции или процедуре данные, можно описать параметр как константу. Ключевое слово const не только защищает параметр от изменения, но и позволяет компилятору сгенерировать более оптимальный код передачи строк и записей. Вот пример объявления параметра-константы:

procedure Test(const s: string );

Передача открытых массивов

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

function AddEmUp(A: array of integer): integer;

В открытом массиве можно передавать переменные, константы или выражения из констант.

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

procedure WhatHaveIGot( A: array of const );

Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.

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

procedure WhatHaveIGot( A: array of const );
var
i: integer;
TypeStr: string;
begin
for i := Low(A) to High(A) do
begin
case A[i].VType of
vtInteger : TypeStr := ‘Integer’;
vtBoolean : TypeStr := ‘Boolean’;
vtChar : TypeStr := ‘Char’;
vtExtended : TypeStr := ‘Extended’;
vtString : TypeStr := ‘String’;
vtPointer : TypeStr := ‘Pointer’;
vtPChar : TypeStr := ‘PChar’;
vtObject : TypeStr := ‘Object’;
vt ;
vtW ;
vtPW ;
vtAnsiString : TypeStr := ‘AnsiString’;
vtCurrency : TypeStr := ‘Currency’;
vtVariant : TypeStr := ‘Variant’;
vtInterface : TypeStr := ‘Interface’;
vtW ;
vtInt64 : TypeStr := ‘Int64’;
end;
ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
end;
end;

Значения параметров по умолчанию

В Delphi есть одна очень полезная возможность — использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:

procedure HasDefVal( s: string; i: integer = 0 );

Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

procedure HasDefVal( ‘Hello’, 26 );

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal( ‘Hello’ );

При использовании значении параметров по умолчанию следует помнить о нескольких приведенных ниже правилах:

  • Параметры, имеющие значения по умолчанию, должны располагаться в конце списка параметров. Параметр без значения по умолчанию не должен встречаться в списке после параметра, имеющего значение по умолчанию.
  • Значения по умолчанию могут присваиваться только параметрам обычных типов, указателям или множествам.
  • Значение по умолчанию может передаваться только по значению либо с модификатором const. Оно не может быть ссылкой или нетипизированным параметром.

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

function Add( I1, I2: integer ): integer;
begin
Result := I1 + I2;
end;

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

function Add( I1, I2: integer; I3: integer = 0 ): integer;
begin
Result := I1 + I2 + I3;
end;

Директива

Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

Процедура и функция — это ключевые понятия в любом языке программирования, без которых не обходится ни одна серьезная программа. И поэтому очень важно иметь полное понимание о механизме их работы.

Функции Delphi модуля System

Модуль System

Предлагаем список функций модуля System, используемого в среде разработки Delphi.

Abs Предназначена для получения абсолютной величины числа
Addr Возвращает адрес переменной, функции или процедуры
ArcTan Арктангенс числа, возвращается в радианах
Assigned Осуществляет проверку функциональности указателей, объектов, методов
BeginThread Начинает отдельный поток выполнения кода
Chr Конвертирует целое число в символ
Concat Соединяет несколько строк в одну
Copy Создает копию части строки или части массива
Cos Косинус числа
Eof Возвращает true, если позиция курсора находится в конце файла открытого с помощью Reset
Eoln Возвращает true, если позиция курсора находится в конце строки
Exp Выдаёт экспоненту числа
FilePos
FileSetDate Установка даты и времени последнего изменения файла
FileSize Выдает размер открытого файла в записях
GetLastError Выдаёт код ошибки последнего неудачного Windows API вызова.
GetMem Получает указанное число байтов памяти.
Hi Возвращает байт старшего разряда от типа Integer.
High Возвращает самое высокое значение типа или переменной
Int Целая часть числа с плавающей точкой
IOResult Содержит возвращаемый код последней операции ввода/вывода
IsMultiThread Возвращает True, если код выполняет множество потоков
Length Возвращает число элементов в массиве или строке
Ln Выдает натуральный логарифм числа
Lo Возвращает младший байт целого числа (2-байтового)
Low Возвращает самое низкое значение типа или переменной
Odd Провеяет, является ли целое число нечетным
Ord Порядковое значение целого числа, символа или перечисления
ParamCount Выдает число параметров переданной текущей программе
ParamStr Возвращается один из параметров используемых для запуска текущей программы
Pi Математическая константа
Pos Находит позицию одной строки в другой
Pred Уменьшает порядковую переменную
Random Генерирует случайное целое число или число с плавающей запятой
Round Округление чисел с плавающей запятой до целого числа
RunError Заканчивает программу с диалогом ошибки
SeekEof Пропускает символы, пока не встретится конец файла
SeekEoln Пропускает символы, пока не встретится конец текущей строки или файла
Sin Синус числа
SizeOf Возвращает занимаемый размер типа или переменной в байтах
Slice Создает часть массива с параметром «Открытый Массив»
Sqr Возвращает квадрат числа
Sqrt Возвращает квадратный корень числа
StringOfChar Создает строку из одного символа, повторенного много раз
StringReplace Заменяет одну или несколько подстрок, найденных в заданной строке
StringToWideChar Преобразует обычную строку в WideChar-буфер с завершающим 0
Trunc Целая часть числа с плавающей запятой
UpCase Преобразует значение Char к верхнему регистру
WideCharToString Копирует строку WideChar, заканчивающуюся нулём, в нормальную строку
Append Открывает текстовый файл, для добавления записей в файл (добавляет в конец файла)
Assign Назначает дескриптор файла на бинарный или текстовый файл
AssignFile Связывает дескриптор файла с бинарным или текстовым файлом
BlockRead Читает блок записей данных из нетипизированного двоичного файла
BlockWrite Записывает блок записей данных в нетипизированный двоичный файл
Break Выполняет выход из одного цикла
ChDir Выбор диска и директории ( папки ), в которой будет производиться работа
Close Закрывает открытый файл
CloseFile Закрывает открытый файл
Continue Заставляет перейти к следующей итерации цикла
Dec Декремент порядковой переменной
Delete Удаляет часть символов из строки
Dispose Очищает память на которую указывает указатель
EndThread Заканчивает поток с кодом завершения
Erase Стирает файл
Exclude Исключает значение из переменной набора (множества)
Exit Осуществляет выход из функции или процедуры
Frac Дробная часть числа с плавающей запятой
FillChar Заполняет раздел памяти значением байта или символа-заполнителя
Flush Сбрасывает буферизованные данные текстового файла в файл
GetDir Получает текущий каталог (диск плюс путь) для указанного диска.
Halt Заканчивает программу с дополнительным диалогом.
Inc Увеличивает порядковую переменную
Include Включает значение во множество переменных
Insert Вставляет строку в другую строку
MkDir Создаёт каталог
Move Копирует байты данных из источника в место назначения
New Создаёт новую переменную типа указатель
Randomize Устанавливает генератор случайного числа на следующее значение
Read Позволяет прочитать данные из двоичного или текстового файла
ReadLn Позволяет прочитать полную строку данных из текстового файла
ReallocMem Позволяет изменить размер существующего блока памяти
Reset Открывает текстовый файл для чтения, или двоичный файл для чтения/записи
ReWrite Открывает текстовый или двоичный файл для записи
RmDir Удаление каталога
Seek Перемещает указатель в двоичном файле в новую позицию
SetLength Изменяет размер строки или размер динамического массива
SetString Копирует символы из буфера в строку
Str Конвертирует целое число или число с плавающей точкой в строку
Truncate Уменьшает размер файла — удаляя все данные после текущей позиции
WriteLn Записывает законченную строку данных в текстовый файл

Поиск этой функции в delphi MD5 (tmpBuffer, sizeof (opera_salt) + DES_KEY_SZ, hashSignature1);

Я переношу операнд из уже существующего кода на С++

Я ударил эту функцию

Где я могу получить этот блок MD5?

steve0, код в вашей ссылке на реализацию md5 openssl, вы можете найти оригинальное объявление функции MD5, используемой в коде в этой ссылке

вы можете использовать блок MessageDigest_5 (начиная с Delphi 2007) для вычисления md5 для буфера или класса TIdHashMessageDigest5 из компоненты indy.

Что все интерфейсы зависят от <$ IOChecks OFF>?

У нас есть какой — нибудь древний код Delphi (возможно, даже возник как Turbo Pascal код) , который использует <$I->, так называемый , что делает использование кода IOResult вместо исключений для ошибок ввода / вывода диска. <$ IOCHECKS OFF>

Я хочу , чтобы избавиться от <$I->и довести этот код вперед в 1990 — е годы, но , чтобы сделать это, я хотел бы знать , что все зависит от <$IOCHECKS OFF>. Означает ли это только влияет на crufty старые встроенные функции ввода / вывода , как AssignFile / Reset / Rewrite / Append / CloseFile? Или же это влияет на более современные вещи , как TFileStream, а? Что еще более важно, что еще может повлиять , что я не думал? ( Delphi Основа предполагает , что он также влияет на MKDIR и RmDir. Если это влияет на тех, там должна быть больше.)

Delphi 2007 раздел справки Ввод вывода проверки (Delphi) ( ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html ) говорит , что это влияет на процедуру ввода / вывода [s], и что I / O процедуры описаны в руководстве по Delphi Language . Это не помогает, так как CodeGear никогда не отгрузил Руководство языка, и последний раз , когда Borland поставляется один был Delphi 5.

Какие функции и классы ведут себя по- разному в <$I->?

EDIT: Принятый ответ дает некоторый большой фон, но вот краткое резюме в виде списка в алфавитном порядке: <$IOCHECKS OFF>только затрагивает следующие подпрограммы из системного блока.

  • присоединять
  • BlockRead
  • BlockWrite
  • ChDir
  • CloseFile
  • Eof
  • Eoln
  • стирать
  • FilePos
  • Размер файла
  • Промывать
  • MkDir
  • Читать
  • ReadLn
  • переименовывать
  • Сброс
  • перезапись
  • RmDir
  • Искать
  • SeekEof
  • SeekEoln
  • SetLineBreakStyle
  • усекать
  • Написать
  • Writeln

поскольку $I как директива компилятора, это может повлиять только компилятор сгенерированного кода, и это может повлиять только код , который на самом деле получает скомпилированный.

По этим двум причинам он не может влиять на такие вещи , как TFileStream . Это класс classes.pas , который является единицей не компилировать. Любой код , в нем не зависит от $I директивы. Кроме того, компилятор не обрабатывает этот класс специально каким — либо образом. Это просто еще один обычный класс.

$I Директива влияет на языковые встроенные функции , которые вы упомянули. Компилятор генерирует вызовы этих функций специально. Это также влияет на звонки write , writeln и readln . Оно также должно повлиять BlockRead и BlockWrite .

Вы можете проверить исходный код. Все , что вызывает SetInOutRes подвержен $I . Это включает в себя функции, открытые файлы ( Append , Reset и Rewrite ), а также все остальное , что принимает параметр типа file или TextFile ( Flush , BlockRead , BlockWrite , Erase , FilePos , Seek , FileSize , Read , Readln , Write , Writeln , Rename , Eof , SeekEof , Eoln , SeekEol , Truncate , SetLineBreakStyle , и CloseFile ). Кроме того , все , что вызывает InOutError ( ChDir , MkDir , драмы RmDir ).

В частности отсутствуют в списке AssignFile . Эта функция фактически не делать какой — либо ввод / вывода. Он просто устанавливает запись файла , так что Append , Reset и Rewrite будет знать , что делать.

Я должен отметить, что , глядя на исходный код просто умозаключение. $I Директива управляет , будет ли компилятор вставить вызовы к __IOTest функции в собственном коде после вызова некоторых других функций. Эта функция проверяет значение InOutRes , и если это не ноль, то возникает ошибка времени выполнения (который может возникнуть исключение , если SysUtils включен в программу). Мы не можем проверить исходный код непосредственно выяснить , какие функции влияет $I (так как он вызывается только в сгенерированного компилятором кода), так что мы на самом деле просто ищет какие функции набора InOutRes , с предположением , что они не будут беспокоить делать , что если они не знали , что компилятор будет проверять его позже.

Файловые функции DELPHI. Файловые операции средствами ShellApi.

В Delphi существует понятие — подпрограммы управления файлами ( category File management routines). Процедуры и функции входящие в эту категорию находятся в модулях System, SysUtils (каталог Source\Rtl\Sys) и FileCtrl (каталог Source\Vcl). Модуль FileCtrl содержит только две функции из категории подпрограмм управления файлами — это DirectoryExists и ForceDirectories. Местонахождение остальных процедур и функций определяется следующим образом. Если в подпрограмме используется файловая переменная, то она входит в модуль System. Если дескриптор или имя файла в виде строки, то в модуль SysUtils. Правда есть исключения (интуитивно понятные) ChDir входит в System. Также в System входят MkDir, RmDir из категории ввода/вывода ( I/O routines). Надо отметить, что все подпрограммы, отнесенные к категориям ввода/вывода и текстовых файлов ( Text file routines) находятся в модуле System (исключая процедуру AssignPrn входящую в модуль Printers каталог Source\Vcl). Вот список подпрограмм отсортирован по категориям и по алфавиту.

File management routines — подпрограммы управления файлами

S ystem procedure AssignFile(var F; FileName: string); Связывает файловую переменную с именем файла
System procedure ChDir(S: string); Изменяет текущий каталог
System procedure CloseFile(var F); Закрывает файл по файловой переменной
SysUtils function CreateDir(const Dir: string): Boolean; Создает новый каталог
SysUtils function DeleteFile(const FileName: string): Boolean; Удаляет файл
FileCtrl function DirectoryExists(Name: string): Boolean; Проверяет наличие каталога
SysUtils function DiskFree(Drive: Byte): Int64; Определяет свободное пространство на диске
SysUtils function DiskSize(Drive: Byte): Int64; Определяет полный размер диска
SysUtils function FileAge(const FileName: string): Integer; Определяет время последнего обновления
SysUtils procedure FileClose(Handle: Integer); Закрывает файл по дескриптору
SysUtils function FileDateToDateTime(FileDate: Integer): TDateTime; Преобразует DOS-дату в Delphi-дату
SysUtils function FileExists(const FileName: string): Boolean; Проверяет наличие файла
SysUtils function FileGetAttr(const FileName: string): Integer; Определяет атрибуты файла
SysUtils function FileGetDate(Handle: Integer): Integer; Определяет время последнего обновления
SysUtils function FileOpen(const FileName: string; Mode: LongWord): Integer; Открывает существующий файл
SysUtils function FileRead(Handle: Integer; var Buffer; Count: Integer): Integer; Читает из файла
SysUtils function FileSearch(const Name, DirList: string): string; Ищет файл в списке каталогов
SysUtils function FileSeek(Handle, Offset, Origin: Integer): Integer; Меняет позицию указателя
SysUtils function FileSetAttr(const FileName: string; Attr: Integer): Integer; Устанавливает атрибуты файла
SysUtils function FileSetDate(Handle: Integer; Age: Integer): Integer; Устанавливает время последнего обновления
SysUtils function FileWrite(Handle: Integer; const Buffer; Count: Integer): Integer; Записывает в файл
SysUtils procedure FindClose(var F: TSearchRec); Прекращает поиск файлов
SysUtils function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; Начинает поиск файлов
SysUtils function FindNext(var F: TSearchRec): Integer; Продолжает поиск файлов
FileCtrl function ForceDirectories(Dir: string): Boolean; Создает все каталоги пути
SysUtils function GetCurrentDir: string; Определяет текущий каталог
System procedure GetDir(D: Byte; var S: string); Определяет текущий каталог
SysUtils function RemoveDir(const Dir: string): Boolean; Удаляет каталог
SysUtils function RenameFile(const OldName, NewName: string): Boolean; Переименовывает файл
SysUtils function SetCurrentDir(const Dir: string): Boolean; Устанавливает текущий каталог

I/O routines — подпрограммы ввода/вывода

Модуль Подпрограмма
System procedure Append(var F: Text); Добавляет текст в конец файла
System procedure BlockRead(var F: File; var Buf; Count: Integer [; var AmtTransferred: Integer]); Читает блок из файла
System procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]); Записывает блок в файл
System function Eof(var F): Boolean; Определяет конец файла
System function FilePos(var F): Longint; Определяет позицию указателя
System function FileSize(var F): Integer; Определяет размер файла
System function IOResult: Integer; Определяет ошибки предыдущего ввода/вывода
System procedure MkDir(S: string); Создает каталог
System procedure Rename(var F; Newname:string); Переименовывает файл
System procedure Reset(var F [: File; RecSize: Word ] ); Открывает файл
System procedure Rewrite(var F: File [; Recsize: Word ] ); Создает и открывает новый файл
System procedure RmDir(S: string); Удаляет каталог
System procedure Seek(var F; N: Longint); Устанавливает позицию указателя
System procedure Truncate(var F); Усекает файл до текущей позиции указателя

Text file routines — подпрограммы текстовых файлов

Модуль Подпрограмма
Printers procedure AssignPrn(var F: Text); Связывает файловую переменную с принтером
System function Eoln [(var F: Text) ]: Boolean; Определяет конец строки
System procedure Erase(var F); Удаляет файл
System procedure Flush(var F: Text); Переписывает данные в файл из его буфера
System procedure Read(F , V1 [, V2. Vn ] ); Читает из файла
System procedure Readln([ var F: Text; ] V1 [, V2, . Vn ]); Читает из файла до конца строки
System function SeekEof [ (var F: Text) ]: Boolean; Определяет конец файла
System function SeekEoln [ (var F: Text) ]: Boolean; Определяет конец строки
System procedure SetTextBuf(var F: Text; var Buf [ ; Size: Integer] ); Устанавливает новый буфер
System procedure Write(F, V1 [, V2. Vn ] ); Записывает в файл
System procedure Writeln([ var F: Text; ] V1 [, V2, . Vn ] ); Записывает в файл с концом строки

Проверяем наличие файла и записываем его
type
TFileData=record
Name:String[10];
ExtDat:Extended;
end;
var
Cals: File of TFileData;
CalsData: TFileData;

procedure NAME;
//Описание процедуры
var p: Real;
u: Byte;
begin
Road:=’<файл>.dat’;
Dest:=’<каталог>‘+Road;
try
AssignFile(Cals,Dest);
// Если файл существует открываем на чтение, иначе создаем новый
If FileExists(Cals) then Reset(cals) else Rewrite(cals);
// установим позицию чтения в конец файла
seek (cals,filesize(cals));
CalsData.Name := ‘название параметра’;
CalsData.ExtDat := <сами данные>;
Write(Cals,CalsData);
except
on E: EInOutError do
ShowMessage(‘При выполнении файловой операции возникла ошибка’+
‘ № ‘+ IntToStr(E. ErrorCode)+’: ‘+SysErrorMessage(GetLastError));
on E: EAccessViolation do
ShowMessage(‘Ошибка!: ‘+SysErrorMessage(GetLastError));
end;
CloseFile(cals); //Независимо от того что произошло выше закрываем открытый файл
end;

Перепишем файл a.dat в файл b.dat, удалив признаки конца файла:

Proedure MyWrite;
var
f1,f2 :file of Byte;
a :Byte;
i :Longint;
begin
<$I->
AssignFile(f1, ‘a.dat’);
AssignFile(f2, ‘b.dat’);
Reset(f1);
Rewrite(f2);
for i := 1 to FileSize(f1) do
begin
Read(f1, a);
if a <> 26 then Write(f2, a);
end;
CloseFile(f1);
CloseFile(f2);
end.

Файл записей. Пишем и читаем любую:

Procedure MyBook;
type TR=Record
Name:string[100];
Age:Byte;
Income:Real;
end;
var f:file of TR;
r:TR;
begin
//assign file
assignFile(f, ‘MyFileName’);
//open file
if FileExists(‘MyFileName’) then
reset(f)
else
rewrite(f);
//чтение 10й записи
seek(f,10);
read(f,r);
//запись 20й записи
seek(f, 20);
write(f,r);
closefile(f);
end;

Файловые операции средствами ShellAPI.


Автор: Владимир Татарчевский

Рассмотрим применение функции SHFileOperation.
function SHFileOperation(const lpFileOp: TSHFileOpStruct): Integer; stdcall;
Функция позволяет производить копирование, перемещение, переименование и удаление (в том числе и в Recycle Bin) объектов файловой системы.
Функция возвращает 0, если операция выполнена успешно, и ненулевое значение в противном случае.

Функция имеет единственный аргумент — структуру типа TSHFileOpStruct, в которой и передаются все необходимые данные. Эта структура выглядит следующим образом:

_SHFILEOPSTRUCTA = packed record
Wnd: HWND;
wFunc: UINT;
pFrom: PAnsiChar;
pTo: PAnsiChar;
fFlags: FILEOP_FLAGS;
fAnyOperationsAborted: BOOL;
hNameMappings: Pointer;
lpszProgressTitle: PAnsiChar; < используется только при установленном флаге FOF_SIMPLEPROGRESS >
end;

Поля структуры имеют следующее назначение:
hwnd Хэндл окна, на которое будут выводиться диалоговые окна о ходе операции.
wFunc Требуемая операция. Может принимать одно из значений:

FO_COPY Копирует файлы, указанные в pFrom в папку, указанную в pTo.
FO_DELETE Удаляет файлы, указанные pFrom (pTo игнорируется).
FO_MOVE Перемещает файлы, указанные в pFrom в папку, указанную в pTo.
FO_RENAME Переименовывает файлы, указанные в pFrom.
pFrom — указатель на буфер, содержащий пути к одному или нескольким файлам. Если файлов несколько, между путями ставится нулевой байт. Список должен
заканчиваться двумя нулевыми байтами.

pTo — аналогично pFrom, но содержит путь к директории — адресату, в которую производится копирование или перемещение файлов. Также может
содержать несколько путей. При этом нужно установить флаг FOF_MULTIDESTFILES.

fFlags — управляющие флаги.
FOF_ALLOWUNDO Если возможно, сохраняет информацию для возможности UnDo.
FOF_CONFIRMMOUSE Не реализовано.
FOF_FILESONLY Если в поле pFrom установлено *.*, то операция будет производиться только с файлами.
FOF_MULTIDESTFILES Указывает, что для каждого исходного файла в поле pFrom указана своя директория — адресат.
FOF_NOCONFIRMATION Отвечает «yes to all» на все запросы в ходе опеации.
FOF_NOCONFIRMMKDIR Не подтверждает создание нового каталога, если операция требует, чтобы он был создан.
FOF_RENAMEONCOLLISION В случае, если уже существует файл с данным именем, создается файл с именем «Copy #N of. »
FOF_SILENT Не показывать диалог с индикатором прогресса.
FOF_SIMPLEPROGRESS Показывать диалог с индикатором прогресса, но не показывать имен файлов.
FOF_WANTMAPPINGHANDLE Вносит hNameMappings элемент. Дескриптор должен быть освобожден функцией SHFreeNameMappings.
fAnyOperationsAborted
Принимает значение TRUE если пользователь прервал любую файловую операцию до ее завершения и FALSE в ином случае.

hNameMappings — дескриптор объекта отображения имени файла, который содержит массив структур SHNAMEMAPPING. Каждая структура содержит старые и новые имена пути для каждого файла, который перемещался, был скопирован, или переименован. Этот элемент используется только, если установлен флаг FOF_WANTMAPPINGHANDLE.

lpszProgressTitle — указатель на строку, используемую как заголовок для диалогового окна прогресса. Этот элемент используется только, если установлен флаг FOF_SIMPLEPROGRESS.

Примечание. Если pFrom или pTo не указаны, берутся файлы из текущей директории. Текущую директорию можно установить с помощью функции
SetCurrentDirectory и получить функцией GetCurrentDirectory.

Добавьте в секцию uses модуль ShellAPI, в котором определена функция SHFileOperation.

procedure TForm1.Button1Click(Sender: TObject);
var
SHFileOpStruct : TSHFileOpStruct;
From : array [0..255] of Char;
begin
SetCurrentDirectory( PChar( ‘C:\’ ) );
From := ‘Test1.tst’ + #0 + ‘Test2.tst’ + #0 + #0;
with SHFileOpStruct do
begin
Wnd := Handle;
wFunc := FO_DELETE;
pFrom := @From;
pTo := nil;
fFlags := 0;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end;
SHFileOperation( SHFileOpStruct );
end;

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

Напишем функцию, создающую из массива строк буфер для передачи его в качестве параметра pFrom. После
каждой строки в буфер вставляется нулевой байт, в конце списка — два нулевых байта.
type TBuffer = array of Char;

procedure CreateBuffer( Names : array of string; var P : TBuffer );
var I, J, L : Integer;
begin
for I := Low( Names ) to High( Names ) do
begin
L := Length( P );
SetLength( P, L + Length( Names[ I ] ) + 1 );
for J := 0 to Length( Names[ I ] ) — 1 do
P[ L + J ] := Names[ I, J + 1 ];
P[ L + J ] := #0;
end;
SetLength( P, Length( P ) + 1 );
P[ Length( P ) ] := #0;
end;

Функция, удаляющая файлы, переданные ей в списке Names. Параметр ToRecycle определяет, будут ли файлы перемещены в корзину или удалены. Функция возвращает 0, если операция выполнена успешно, и ненулевое значение, если функции переданы имена несуществующих файлов.
function DeleteFiles( Handle : HWnd; Names : array of string; ToRecycle : Boolean ) : Integer;
var
SHFileOpStruct : TSHFileOpStruct;
Src : TBuffer;
begin
CreateBuffer( Names, Src );
with SHFileOpStruct do
begin
Wnd := Handle;
wFunc := FO_DELETE;
pFrom := Pointer( Src );
pTo := nil;
fFlags := 0;
if ToRecycle then fFlags := FOF_ALLOWUNDO;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end;
Result := SHFileOperation( SHFileOpStruct );
Src := nil;
end;

Освобождаем буфер Src простым присваиванием значения nil. Потери памяти при этом не происходит, происходит корректное уничтожение динамического массива.

Проверяем :
procedure TForm1.Button1Click(Sender: TObject);
begin
DeleteFiles( Handle, [ ‘C:\Test1’, ‘C:\Test2’ ], True );
end;

Файлы ‘Test1’ и ‘Test2’ удаляются совсем, без помещения в корзину, несмотря на установленный флаг FOF_ALLOWUNDO. При использовании функции SHFileOperation используйте полные пути, когда это возможно.

Копирование и перемещение.

Функция перемещает файлы указанные в списке Src в директорию Dest. Параметр Move определяет, будут ли файлы перемещаться или копироваться. Параметр AutoRename указывает, переименовывать ли файлы в случае конфликта имен.
function CopyFiles( Handle : Hwnd; Src : array of string; Dest : string; Move : Boolean; AutoRename : Boolean ) : Integer;
var
SHFileOpStruct : TSHFileOpStruct;
SrcBuf : TBuffer;
begin
CreateBuffer( Src, SrcBuf );
with SHFileOpStruct do
begin
Wnd := Handle;
wFunc := FO_COPY;
if Move then wFunc := FO_MOVE;
pFrom := Pointer( SrcBuf );
pTo := PChar( Dest );
fFlags := 0;
if AutoRename then fFlags := FOF_RENAMEONCOLLISION;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end;
Result := SHFileOperation( SHFileOpStruct );
SrcBuf := nil;
end;

Выполнение:
procedure TForm1.Button1Click(Sender: TObject);
begin
CopyFiles( Handle, [ ‘C:\Test1’, ‘C:\Test2’ ], ‘C:\Temp’, True, True );
end;

Переименование.
function RenameFiles( Handle : HWnd; Src : string; New : string; AutoRename : Boolean ) : Integer;
var SHFileOpStruct : TSHFileOpStruct;
begin
with SHFileOpStruct do
begin
Wnd := Handle;
wFunc := FO_RENAME;
pFrom := PChar( Src );
pTo := PChar( New );
fFlags := 0;
if AutoRename then fFlags := FOF_RENAMEONCOLLISION;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end;
Result := SHFileOperation( SHFileOpStruct );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
RenameFiles( Handle, ‘C:\Test1’ , ‘C:\Test3’ , False );
end;

DelphiComponent.ru — бесплатно видеоуроки по Delphi, статьи, исходники

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

Вот поэтому рекомендуется использовать специализированный в Delphi объект TFiiestream. Вы можете написать и свой класс, который будет делать то же самое, но TFiiestream делает это достаточно хорошо.

У TFileStream есть еще одно преимущество — вам не нужно отслеживать ново­введения от Microsoft. В этой корпорации постоянно появляются новые идеи, из-за которых появляются новые функции, а мы, программисты, должны постоянно изу­чать новинки и переписывать код. Лично я намучился уже с функциями работы с файлами. Их так много, что с первого взгляда даже не поймешь, какие новые и рекомендуются к использованию, а какие устарели. В любом случае, использова­ние этого объекта намного проще, чем WinAPI, поэтому желательно начинать изу­чение работы с файлами именно с него.

Итак, давайте взглянем на объект TFileStream. Первое, что надо сделать, — это объявить какую-нибудь переменную типа TFileStream:

Вот так мы объявили переменную f типа объекта TFileStream. Теперь можно проинициапизировать переменную.

Инициализация — выделение памяти и установка значений по умолчанию. За эти действия отвечает метод create. Нужно просто вызвать его и результат выполнения присвоить переменной. Например, в нашем случае нужно вызвать TFileStream.create и результат записать в переменную f.

Давайте разберемся, какие параметры могут быть при инициализации объекта TFileStream. У метода create может быть три параметра, причем последний мож­но не указывать.

  • Имя файла (или полный путь к файлу), который надо открыть. Этот параметр — простая строка.
  • Режим открытия. Здесь вы можете указать один из следующих параметров открытия файла:
    • fmCreate— создать файл с указанным в первом параметре именем. Если файл уже существует, то он откроется в режиме для записи;
    • fmOpenRead — открыть файл только для чтения. Если файл не существует, то произойдет ошибка. Запись в файл в этом случае не возможна;
    • fmopenwrite — открыть файл для записи. При этом во время записи текущее содержимое уничтожается;
    • fmOpenReadWrite — открыть файл для редактирования (чтения и записи).
  • Права, с которыми будет открыт файл. Здесь можно указать одно из следую­щих значений (а можно вообще ничего не указывать):
    • fmshareCompat — при этих правах другие приложения тоже имеют права ра­ботать с открытым файлом;
    • fmShareExciusive — другие приложения не смогут открыть файл;
      • fmShareDenyWrite — при данном режиме другие приложения не смогут от­крывать этот файл для записи. Файл может быть открыт только для чтения;
      • fmshareDenyRead— при данном режиме другие приложения не смогут от­крывать этот файл для чтения. Файл может быть открыт только для записи;
      • fmShareDenyNone — не мешать другим приложениям работать с файлом.

С первыми двумя параметрами все ясно. Но зачем же нужны права доступа к файлам. Допустим, что вы открыли файл для записи. Потом его открыло другое приложение и тоже для записи. Обе программы записали какие-то данные. После этого ваше приложение закрыло файл и сохранило все изменения. Тут же другое приложение перезаписывает ваши изменения, даже не подозревая о том, что они уже прошли. Вот так ваша информация пропадает из файла, потому что другая программа просто перезаписала ее.

Если вы пишете однопользовательскую программу, и к файлу будет иметь дос­туп только одно приложение, то про права можно забыть и не указывать их.

После того как вы поработали с файлом, достаточно вызвать метод Free, чтобы закрыть его:

Теперь давайте познакомимся с методами чтения, записи и внутренней структу­рой файла. Начнем со структуры. Когда вы открыли файл, позиция курсора уста­навливается в самое начало и любая попытка чтения или записи будет происходить в эту позицию курсора. Если вам надо прочитать или записать в любую другую по­зицию, то надо передвинуть курсор. Для этого есть метод seek. У него есть два па­раметра:

  • Число, указывающее на позицию, в которую надо перейти. Если вам нужно пе­редвинуться на 5 байт, то просто поставьте цифру 5.
  • Откуда надо двигаться. Тут возможны три варианта:
  • soFromBeginning — двигаться на указанное количество байт от начала файла.
    • soFromCurrent — двигаться на указанное количество байт от текущей пози­ции в файле к концу файла.
    • soFromEnd — двигаться от конца файла к началу на указанное количество байт.

Не забывайте, что 1 байт— это один символ. Единственное исключение — файлы в формате Unicode. В них один символ занимает 2 байта. Так образом, надо учитывать, в каком виде хранится информация в файле.

Итак, если вам надо передвинуться на 10 символов от начала файла, можете на­писать следующий код:

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

В следующем примере устанавливается позиция в файле на 0 байт от конца, т. е. в самый конец. Тем самым получается полный размер файла:

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

Для чтения из файла нужно использовать метод Read. И снова у этого метода два параметра:

  • переменная, в которую будет записан результат чтения;
  • количество байт, которые надо прочитать.

Давайте взглянем на код чтения из файла, начиная с 15-й позиции. Этот код вы можете увидеть в листинге

f:TFileStream; //Переменная типа объект

TFileStream. buf: array[0..10] of char; // Буфер для хранения прочитанных данных begin

//В следующей строке я открываю файл filename.txt для чтения и записи,

f:= TFileStream.Create(1 с:\filename.txt’, fmOpenReadWrite);

f.Seek(15, soFromCurrent); // Перемещаюсь на 15 символов вперед,

f.Read(buf, 10); // Читаю 10 символов из установленной позиции.

f.Free; // Уничтожаю объект и соответственно закрываю файл, end;

Обратите внимание, что в методе seek движение происходит на 15 символов не от начала, а от текущей позиции, хотя нужно от начала. Это потому, что после от­крытия файла текущая позиция и есть начало. Но лучше на это не рассчитывать.

Метод Read возвращает количество реально прочитанных байт (символов). Если не возникло никаких проблем, то это число должно быть равно количеству запро­шенных для чтения байт.

Есть только два случая, когда эти числа отличаются:

  • при чтении был достигнут конец файла и дальнейшее чтение стало невозможным;
  • ошибка на диске или любая другая проблема.

Осталось только разобраться с записью. Для этого мы будем использовать метод write. У него так же два параметра:

  • переменная, содержимое которой нужно записать;
  • число байт для записи.

Пользоваться этим методом можно точно так же, как и методом для чтения.

Пример пока рассматривать не будем, потому что в принципе и так все ясно. А если есть вопросы, то на практике мы закрепим этот материал буквально через один или два раздела, когда будем работать со структурами.

Delphi in a Nutshell by Ray Lischner

Stay ahead with the world’s most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to v > Start Free Trial

No credit card required

Syntax

Description

SeekEof skips over white space characters and then returns True if the text file is at the end of file or False if there is more text to read. SeekEof is not a real function.

Errors

If the file F is not open, SeekEof reports runtime error 103.

The file must have been opened by calling Reset . If the file F was opened by calling Rewrite or Append , SeekEof reports runtime error 104.

Работа с JSON в Delphi 2010 — XE2.

Сегодняшняя тема, думаю, будет интересна в первую очередь тем, кто связан с программированием сетевых приложений. Про работу с JSON в Delphi я уже несколько раз рассказывал в блоге и приводил примеры того как можно разбирать различные JSON-объекты. Но во всех примерах я рассматривал работу лишь с одной из библиотек для работы с json в Delphi — SuperObject.

Но не стоит забывать и про то, что в Delphi существуют свои родные механизмы работы с JSON, которые содержатся в трех модулях: DBXJSON.pas, DBXJSONCommon.pas и DBXJSONReflect.pas. В этих трех модулях можно найти достаточно много полезных и интересных классов и методов. Если Вы никогда не слышали об этих модулях, то эта статья как раз для Вас .

Впервые о том, что Delphi теперь «умеет» работать с JSON я узнал после выхода Delphi 2010. Тогда в исходниках были замечены два модуля: DBXJSON.pas и DBXJSONReflect.pas. Ну, а раз именно эти два модуля появились в Delphi первыми, то с них мы и начнем разговор, но прежде, пара слов о формате JSON.

JSON — это текстовый формат обмена данными. В основе этого формате лежит всего пять понятий:

  1. Объект — неупорядоченный набор пар «ключ/значение». Объект всегда начинается с «<» и заканчивается «>».
  2. Массив — упорядоченный коллекция значений. Массив начинается с «[» и заканчивается «]». Элементы массива разделяются запятыми.
  3. Значение — строка в двойных кавычках. Значение может быть: строкой, числом, true, false, null, объектом, массивом.
  4. Строка — набор Unicode-символов.
  5. Число — любое число в десятичной системе счисления.
  1. TJSONObject — объект
  2. TJSONArray — массив
  3. TJSONValue — значение
  4. TJSONString — строка
  5. TJSONNumber — число
  • TJSONString — строка
  • TJSONNumber — число
  • TJSONTrue — true
  • TJSONFalse — false
  • TJSONNull — null

Использование DBXJSON.pas

Чтение данных

Постоянные читатели блога могут сразу догадаться почему именно такой объект я выбрал в качестве примера. Это JSON-объект из Google Tasks API, содержащий список задач. Вначале посмотрим из чего состоит объект.

Вначале объекта идут две пары, содержащие служебную информацию по ответу — kind, значение которого говорит нам, что мы запросили список задач и Etag — идентификатор ответа. Далее следует массив items в котором каждый элемент — это объект, содержащий сведения по отдельной задаче.

При этом следует обратить внимание на то, что каждый JSON-объект задачи может состоять из различных пар.В примере выше Вы можете видеть, что «Задача №1» содержит сведения по сроку выполнения задачи («due«), в то время как «Задача №2» не имеет срока выполнения, но зато отмечена как выполненная («completed«).

Приложение для парсинга JSON

Чтобы наиболее полно охватить работу с DBXJSON.pas, используя предложенный выше JSON-объект, вначале напишем небольшое приложение, которое будет парсить данные из файла, содержащего JSON-объект и «рассказывать» нам о том, что содержится в JSON-объекте и «подсказывать» какой класс будет использоваться для парсинга значений из той или иной пары. Для этого сохраним объект, предложенный выше в текстовый файл с названием testObject.txt, создадим новый проект Delphi-приложения и на главной форме разместим следующие компоненты:

Работа программы будет происходить следующим образом:

  • при открытии очередного файла пробуем разобрать, содержащиеся в файле данные
  • если удалось провести парсинг данных из файла, то записываем в ComboBox имена пар, иначе — сообщаем пользователю о том, что файл не содержит JSON-данных
  • при выборе значения в ComboBox’e выводим значение пары в виде строки в Memo и определяем класс, который необходимо использовать для парсинга значения пары.
Илон Маск рекомендует:  Case средства jam5 1 2 jam
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL