В 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 -
подпрограммы управления файлами
Модуль Подпрограмма
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;
|