Копирование и удаление файлов в Delphi

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

В самом простом случае вопрос копирования файлов очень прост (хотя поступило много пожеланий рассказать именно об этом)! Для этого достаточно посмотреть в хелп по Delphi :))

Копирование файлов
В Delphi есть функция CopyFile. Вот ее описание из хелпа

BOOL CopyFile(
  LPCTSTR lpExistingFileName, // pointer to name of an existing file 
  LPCTSTR lpNewFileName, // pointer to filename to copy to 
  BOOL bFailIfExists // flag for operation if file exists 
);

Параметры передаваемые в эту функцию:

Указатель на имя существующего файла (нуль терминированная строка т.е. тип PChar! )
Указатель на имя файла, который будет создан/перезаписан после копирования (нуль терминированная строка т.е. тип PChar! )
Если этот параметр True и файл с таким именем уже существует, то функция вернет False. Если же файл, с именем указанным во втором параметре существует и в качестве третьего параметра передан False - то функция перезапишет файл и благополучно завершится.
Приведу небольшой пример использования этой функции. Создайте на диске C:\ файл '1.txt', а на форму поставьте кнопку:


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  if CopyFile('c:\1.txt','c:\2.txt',true) then  
  ShowMessage('Файл успешно скопирован!')  
  else ShowMessage('Неудача!');  
end;  

Для того, чтобы точнее узнать при возникновении ошибки, что же все таки произошло, надо воспользоваться функцией GetLastError, которая возвращает код последней ошибки (формат DWORD). Теперь мы немного изменим пример:


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  if CopyFile('c:\1.txt','c:\2.txt',true) then  
    ShowMessage('Файл успешно скопирован!')  
  else  
    ShowMessage('Ошибка! Вот ее код: '+IntToStr(GetLastError));  
end;  

Таким образом нажав второй раз на кнопку мы получим сообщение: "Ошибка! Вот ее код: 80". Это говорит нам, что файл существует.

Коды всех ошибок можно легко найти в хелпе.

Для углубления рассматриваемого вопроса приведу пример копирования файлов с помощью файлового потока (TFileStream). В приведенной пользовательской функции введены два дополнительных параметра From и Count, которые указывают, соответственно, с какого и по какой байт нужно копировать файл. Если необходимо скопировать весь файл, то необходимо передать нули. Вот код этой функции:


function MyCopyFile( InFile,OutFile: String; From,Count: Longint ): Longint;  
var  
  InFS,OutFS: TFileStream;  
begin  
  InFS := TFileStream.Create( InFile, fmOpenRead );//создаем поток  
  OutFS := TFileStream.Create( OutFile, fmCreate );//создаем поток  
  InFS.Seek( From, soFromBeginning );//перемещаем указатель в From  
  Result := OutFS.CopyFrom( InFS, Count );  
  InFS.Free;//освобождаем  
  OutFS.Free;//освобождаем  
end;  

Удаление файлов
Для удаления файлов в Delphi так же предусмотрена специальная процедура DeleteFile. В качестве параметра, передаваемого в функцию, выступает строка типа PChar, указывающая имя файла, который нужно удалить. Сразу предлагаю Вам простой пример на использование этой функции:


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  if DeleteFile('c:\2.txt') then  
    ShowMessage('Файл успешно удален!')  
  else  
  ShowMessage('Ошибка! Вот ее код: '+IntToStr(GetLastError));  
end;  

Удаление пустой директории
Чтобы удалить пустую директорию с помощью Delphi достаточно обратиться к функции RemoveDir.


function RemoveDir(const Dir: string): Boolean;  

Эта функция возвращает True если директория, указанная в единственном параметре, передаваемом в функцию, успешно удалена, в противном случае функция возвратит False.

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


function MyRemoveDir(sDir : String) : Boolean;   
var   
  iIndex : Integer;   
  SearchRec : TSearchRec;   
  sFileName : String;   
begin   
  Result := False;   
  sDir := sDir + '\*.*';   
  iIndex := FindFirst(sDir, faAnyFile, SearchRec);   
  
  while iIndex = 0 do begin   
    sFileName := ExtractFileDir(sDir)+'\'+SearchRec.Name;   
    if SearchRec.Attr = faDirectory then begin   
      if (SearchRec.Name <> '' ) and   
      (SearchRec.Name <> '.') and   
      (SearchRec.Name <> '..') then   
        MyRemoveDir(sFileName);   
      end else begin   
        if SearchRec.Attr <> faArchive then   
        FileSetAttr(sFileName, faArchive);   
        if NOT DeleteFile(sFileName) then   
        ShowMessage('Could NOT delete ' + sFileName);   
    end;   
    iIndex := FindNext(SearchRec);   
  end;   
  
  FindClose(SearchRec);   
  
  RemoveDir(ExtractFileDir(sDir));   
  Result := True;   
end;  

А сейчас пример использования этой функции:


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  if MyRemoveDir('C:\testDir') then ShowMessage('Директория успешно удалена')  
  else ShowMessage('Не получается удалить директорию');  
end;  

Общие замечания по данной теме
Перед копированием или удалением файлов всегда проверяйте его наличие функцией FileExists:

if FileExists('c:\1.txt') then  
 if CopyFile('c:\1.txt','c:\2.txt',true) then  
  ShowMessage('Файл успешно скопирован!')  

Чтобы использовать в функциях CopyFile и DeleteFile имена файлов полученные с помощью, например, OpenDialog, надо из привести к типу PChar:

if CopyFile(Pchar(OpenDialog1.FileName),Pchar(SaveDialog1.FileName),true) then ...  

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

Автор: Михаил Христосенко
Теги:
Копирование, удаление
Добавлено: 02 Августа 2018 08:09:26 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...