В Delphi существует понятие - подпрограммы управления файлами
(category File management routines). Процедуры и функции входящие в эту
категорию находятся в модулях System, SysUtils (каталог
SourceRtlSys) и FileCtrl (каталог SourceVcl). Модуль FileCtrl
содержит только две функции из категории подпрограмм управления файлами - это
DirectoryExists и ForceDirectories. Местонахождение остальных
процедур и функций определяется следующим образом. Если в подпрограмме
используется файловая переменная, то она входит в модуль System. Если
дескриптор или имя файла в виде строки, то в модуль SysUtils. Правда есть
исключения (интуитивно понятные) ChDir входит в System. Также в
System входят MkDir, RmDir из категории ввода/вывода
(I/O routines). Надо отметить, что все подпрограммы, отнесенные к
категориям ввода/вывода и текстовых файлов (Text file routines) находятся
в модуле System (исключая процедуру AssignPrn входящую в модуль
Printers каталог SourceVcl). Вот список подпрограмм отсортирован по
категориям и по алфавиту.
File management routines - подпрограммы управления
файлами
Модуль Подпрограмма
System 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;