|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Код ошибки при копировании файла — 3
, Delphi (чайник)
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Здрасте! var copyringDirSrName,copySaveDir:string; begin copyingDirSrName:=’F:\1.bmp’; copySaveDir:=’C:\’; if (copyFile(pChar(copyringDirSrName),pChar(copySaveDir),true)) then begin showMessage(‘OK!FileCopy!’); end else begin showMessage(‘NO!File Not Copy!Код ошибки =’+inttostr(getlasterror)); end; end; выдает сообщение Цитата NO!File Not Copy!Код ошибки = 3
Я немогу найти код ошибки =3.Не подскажите,что это значит. |
volvo877 |
|
Цитата uborshik @ Я немогу найти код ошибки =3
Здесь смотрел: Цитата uborshik @ я чувствую,что делаю,что-то не так. … copySaveDir:=’C:\1.bmp’; … чувствуешь разницу? |
uborshik |
|
Цитата volvo877 @ чувствуешь разницу?
Гм… |
P.O.D |
|
Цитата uborshik @ Я немогу найти код ошибки =3.Не подскажите,что это значит. ShowMessage(‘NO!File Not Copy! ‘+SysErrorMessage(GetLastError));
|
uborshik |
|
P.O.D,volvo877 Сообщение отредактировано: uborshik — |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0464 ] [ 16 queries used ] [ Generated: 21.09.23, 09:54 GMT ]
Обновлено: 01 декабря, 2018
Основная информация
В 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;
Для того, чтобы точнее узнать при возникновении ошибки, что же все таки произошло, надо воспользоваться функцией GetLastError0, которая возвращает код последней ошибки (формат 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;
Общие замечания
Перед копированием или удалением файлов всегда проверяйте его наличие функцией 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.
Копирование методом TurboPascal
Type {Для индикации процесса копирования} TCallBack=procedure (Position,Size:Longint); procedure FastFileCopy(Const InfileName, OutFileName: String; CallBack: TCallBack); Const BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат } Type PBuffer = ^TBuffer; TBuffer = array [1..BufSize] of Byte; var Size : integer; Buffer : PBuffer; infile, outfile : File; SizeDone,SizeFile: Longint; begin if (InFileName <> OutFileName) then begin buffer := Nil; AssignFile(infile, InFileName); System.Reset(infile, 1); try SizeFile := FileSize(infile); AssignFile(outfile, OutFileName); System.Rewrite(outfile, 1); try SizeDone := 0; New(Buffer); repeat BlockRead(infile, Buffer^, BufSize, Size); Inc(SizeDone, Size); CallBack(SizeDone, SizeFile); BlockWrite(outfile,Buffer^, Size) until Size < BufSize; FileSetDate(TFileRec(outfile).Handle, FileGetDate(TFileRec(infile).Handle)); finally if Buffer <> Nil then Dispose(Buffer); System.close(outfile) end; finally System.close(infile); end; end else Raise EInOutError.Create('File cannot be copied into itself'); end;
Копирование методом потока
Procedure FileCopy(Const SourceFileName, TargetFileName: String); Var S,T : TFileStream; Begin S := TFileStream.Create(sourcefilename, fmOpenRead ); try T := TFileStream.Create(targetfilename, fmOpenWrite or fmCreate); try T.CopyFrom(S, S.Size ) ; FileSetDate(T.Handle, FileGetDate(S.Handle)); finally T.Free; end; finally S.Free; end; end;
Копирование методом LZExpand
uses LZExpand; procedure CopyFile(FromFileName, ToFileName : string); var FromFile, ToFile: File; begin AssignFile(FromFile, FromFileName); AssignFile(ToFile, ToFileName); Reset(FromFile); try Rewrite(ToFile); try if LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle)<0 then raise Exception.Create('Error using LZCopy') finally CloseFile(ToFile); end; finally CloseFile(FromFile); end; end;
Копирование методами Windows
uses ShellApi; // !!! важно function WindowsCopyFile(FromFile, ToDir : string) : boolean; var F : TShFileOpStruct; begin F.Wnd := 0; F.wFunc := FO_COPY; FromFile:=FromFile+#0; F.pFrom:=pchar(FromFile); ToDir:=ToDir+#0; F.pTo:=pchar(ToDir); F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION; result:=ShFileOperation(F) = 0; end; // пример копирования procedure TForm1.Button1Click(Sender: TObject); begin if not WindowsCopyFile('C:\UTIL\ARJ.EXE', GetCurrentDir) then ShowMessage('Copy Failed'); end;
Как скопировать все файлы вместе с подкаталогами
uses ShellApi; procedure TForm1.Button1Click(Sender: TObject); var OpStruc: TSHFileOpStruct; frombuf, tobuf: Array [0..128] of Char; Begin FillChar( frombuf, Sizeof(frombuf), 0 ); FillChar( tobuf, Sizeof(tobuf), 0 ); StrPCopy( frombuf, 'h:\hook\*.*' ); StrPCopy( tobuf, 'd:\temp\brief' ); With OpStruc do begin Wnd:= Handle; wFunc:= FO_COPY; pFrom:= @frombuf; pTo:=@tobuf; fFlags:= FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION; fAnyOperationsAborted:= False; hNameMappings:= Nil; lpszProgressTitle:= Nil; end; ShFileOperation( OpStruc ); end;
Копирование группы файлов, используя диалог с анимацией «Копирование Файлов», который использует «Проводник»
В следующем примере используется функция SHFileOperation для копирования группы файлов и показа анимированного диалога. Вы можете использовать также следующие флаги для копирования, удаления, переноса и переименования файлов.
TO_COPY FO_DELETE FO_MOVE FO_RENAME
Примечание: буфер, содержащий имена файлов для копирования должен заканчиваться двумя нулевыми символами.
uses ShellAPI; procedure TForm1.Button1Click(Sender: TObject); var Fo : TSHFileOpStruct; buffer: array[0..4096] of char; p : pchar; begin FillChar(Buffer, sizeof(Buffer), #0); p := @buffer; p := StrECopy(p, 'C:\DownLoad\1.ZIP') + 1; p := StrECopy(p, 'C:\DownLoad\2.ZIP') + 1; p := StrECopy(p, 'C:\DownLoad\3.ZIP') + 1; StrECopy(p, 'C:\DownLoad\4.ZIP'); FillChar(Fo, sizeof(Fo), #0); Fo.Wnd := Handle; Fo.wFunc := FO_COPY; Fo.pFrom := @Buffer; Fo.pTo := 'D:\'; Fo.fFlags := 0; if ((SHFileOperation(Fo) <> 0) or (Fo.fAnyOperationsAborted <> false)) then ShowMessage('Cancelled') end;
Автор статьи
Программист Delphi, MySQL. Образование: высшее. Специальность: программное обеспечение информационных технологий.
(11 оценок, среднее: 5,00 из 5)
Загрузка…
Albershell1 0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
||||
1 |
||||
18.06.2023, 16:14. Показов 972. Ответов 40 Метки нет (Все метки)
При копировании CopyFileW файла .exe выдаёт код ошибки 2:
пробовал PWideChar, выдаёт ошибку invalid typecast
0 |
droider 4901 / 2771 / 851 Регистрация: 04.10.2012 Сообщений: 10,095 |
||||
18.06.2023, 16:20 |
2 |
|||
CopyFileW обычный CopyFile чем не угодил?
0 |
Модератор 8590 / 5733 / 2306 Регистрация: 21.01.2014 Сообщений: 24,568 Записей в блоге: 3 |
|
18.06.2023, 16:21 |
3 |
А посмотреть-то не судьба, что за ошибка? А она очень простая — не найден копируемый файл. И это справедливо — на кой ляд в имени исходного файла слэш на конце?
0 |
2265 / 605 / 57 Регистрация: 21.04.2013 Сообщений: 5,925 |
|
18.06.2023, 16:36 |
4 |
выдаёт код ошибки 2 На будущее, что значат коды ошибок смотреть здесь: Коды ошибок Microsoft Windows
0 |
0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
|
18.06.2023, 17:09 [ТС] |
5 |
Убрал слэш, не помогло, не находит файл, код ошибка 2, вроде путь указан правильно Добавлено через 4 минуты
0 |
4901 / 2771 / 851 Регистрация: 04.10.2012 Сообщений: 10,095 |
|
18.06.2023, 17:10 |
6 |
Убрал слэш, не помогло Вы использовали CopyFile как я написал?
вроде путь указан правильно Файл по указанному пути есть? Он не скрыт?
0 |
Модератор 8590 / 5733 / 2306 Регистрация: 21.01.2014 Сообщений: 24,568 Записей в блоге: 3 |
|
18.06.2023, 17:28 |
7 |
вроде путь указан правильно «вроде» или «правильно»?
0 |
Albershell1 0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
||||
18.06.2023, 17:53 [ТС] |
8 |
|||
Каталог существует:
он пустой, а путь прописан правильно
0 |
4901 / 2771 / 851 Регистрация: 04.10.2012 Сообщений: 10,095 |
|
18.06.2023, 18:04 |
9 |
он пустой
0 |
403 / 132 / 27 Регистрация: 04.08.2018 Сообщений: 585 |
|
18.06.2023, 18:10 |
10 |
Там нет файла «ExtHisMed.exe», который Вы пытаетесь скопировать в другую папку. Копируется файл из DifDiagnoseStr в ExtHisMed.
0 |
4901 / 2771 / 851 Регистрация: 04.10.2012 Сообщений: 10,095 |
|
18.06.2023, 18:24 |
11 |
Копируется файл из DifDiagnoseStr кстати, да. Albershell1, в каталоге DifDiagnoseStr есть файл «ExtHisMed.exe»? Вы чего-то не договариваете.
0 |
0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
|
18.06.2023, 18:30 [ТС] |
12 |
В папке DifDiagnoseStr есть файл ExtHisMed.exe. Он в процессе работы приложения заполняется определённой информацией, затем в финале все попытки скопировать его в каталог D:\ExtHisMed тщетны
0 |
Модератор 3472 / 2027 / 722 Регистрация: 15.11.2015 Сообщений: 8,081 |
|
18.06.2023, 19:01 |
13 |
файл ExtHisMed.exe. Он в процессе работы приложения заполняется определённой информацией Это какой-то супер-пупер вирус собирается, что ли? Добавлено через 3 минуты
0 |
0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
|
18.06.2023, 19:22 [ТС] |
14 |
Приложение «История болезни больного». В исходном каталоге файл ExtHisMed.exe заполняется информацией о состоянии больного. На выходе (копирование) — выписка из истории болезни
0 |
Модератор 8590 / 5733 / 2306 Регистрация: 21.01.2014 Сообщений: 24,568 Записей в блоге: 3 |
|
18.06.2023, 19:27 |
15 |
файл ExtHisMed.exe заполняется информацией о состоянии больного файл ExtHisMed.exe —
0 |
0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
|
18.06.2023, 19:31 [ТС] |
16 |
Так и текстовый файл .txt из этого каталога скопировать не получается Миниатюры
0 |
Модератор 8590 / 5733 / 2306 Регистрация: 21.01.2014 Сообщений: 24,568 Записей в блоге: 3 |
|
18.06.2023, 19:42 |
17 |
скопировать не получается сам код, как таковой, ошибок не содержит. Или неверны пути или нет прав скопировать файлы из указанного каталога.
0 |
0 / 0 / 0 Регистрация: 20.12.2017 Сообщений: 16 |
|
18.06.2023, 19:50 [ТС] |
18 |
Директории указаны правильно. Насчёт прав буду разбираться
0 |
13 / 10 / 4 Регистрация: 21.10.2022 Сообщений: 131 |
|
18.06.2023, 20:18 |
19 |
Так и текстовый файл .txt из этого каталога скопировать не получается Не по теме: О, боже! Скажите мне, что это школьная работа, а не реальное приложение! И это… Не знаю как в Дельфях, а в Билдере слеши приходиться удваивать.
0 |
200 / 169 / 33 Регистрация: 19.02.2021 Сообщений: 1,117 |
|
18.06.2023, 20:35 |
20 |
И это… Не знаю как в Дельфях, а в Билдере слеши приходиться удваивать. Там, где распознаются и обрабатываются спецсимволы, типа \n, \t и т.д., слеши нужно экранировать, чтобы следующий за слешом символ не распознавался, как спецсимвол.
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
18.06.2023, 20:35 |
20 |
Копирование файлов
Нет другого такого процесса в программе инсталляции, который бы выглядел снаружи столь простым и был бы в реализации столь сложным, как копирование. Сложная фраза. В переводе на русский язык она означает, что сделать хорошую операцию копирования файлов нелегко
Почему?
Потому что операция копирования файлов должна быть идеальной.
Начнём с самого просто случая — копирования одного файла. Для того, чтобы скопировать один файл, вы можете вызвать функцию Windows, которая называется CopyFile:
function CopyFile(lpExistingFileName, lpNewFileName: PChar; bFailIfExists: BOOL): BOOL; stdcall;
Как видим, функции необходимо передать имена двух файлов: исходного и целевого. Третий параметр отвечает за то, как функция будет поступать, если целевой файл уже существует. Значение True говорит о том, что функция не будет копировать файл, значение False — о том, что целевой файл будет перезаписан.
Функция возвращает True, если операция копирования была успешно выполнена. Значение False подсказывает нам, что необходимо вызвать функцию GetLastError для того, чтобы узнать код произошедшей ошибки.
Эта функция работает очень надёжно, поскольку она является частью операционной системы и практически наверняка именно она тестировалась огромное количетво раз. Тем не менее, первое, на чём мы остановимся — что в этой функции нас не устраивает?
if CopyFile(PChar(SourcePath), PChar(TargetPath), False) then // Выполнилась успешно. else // Ошибка. Код ошибки можно получить, вызвав GetLastError.
У этой функции один недостаток, но он способен перекрыть все её достоинства. Мы не имеем доступа к процессу копирования. Это означает, что мы не можем показывать индикатор процесса копирования и не можем прервать функцию CopyFile, если пользователь нажал кнопку «Отмена» или клавишу Escape.
Насколько это важно? На этот вопрос вы вольны отвечать самостоятельно. Если вам потребуется копировать большое количество маленьких файлов, то для вас этот недостаток неважен. Если вы собираетесь копировать файлы размером в несколько мегабайт, то у пользователя вашей программы могут возникнуть определённые проблемы.
В Windows NT 4.0 появилась новая функция — CopyFileEx, которая позволяет снять все появившиеся проблемы, но добавляет ещё одну — она не работает в Windows 95.
В Delphi для копирования файлов, мы можем воспользоваться объектами класса
TFileStream. Например, так:
procedure CopyFile(Source, Target: String); var SourceStream: TFileStream; TargetStream: TFileStream; begin SourceStream := TFileStream(Source, fmOpenRead); try TargetStream := TFileStream(Target, fmCreate); try TargetStream.CopyFrom(SourceStream, 0); FileSetDate(TargetStream.Handle, FileGetDate(SourceStream.Handle)); finally TargetStream.Free; end; finally SouceStream.Free; end; FileSetAttr(Target, FileGetAttr(Source)); end;
Обработку ошибок, как говорится в таких случаях, я оставляю читателю в качестве упражнения…
Немного поговорим о приведённой процедуре. Саму операцию копирования выполняет метод CopyFrom. Если второй параметр этого метода равен нулю, то копируется сразу весь файл, в ином случае копируется указанное количество байтов. Мы можем копировать файл блоками, со всеми вытекающими отсюда преимуществами:
. . . const BlockSize = 65536; . . . var ElapsedSize: Integer; CopySize: Integer; . . . ElapsedSize := SourceStream.Size - SourceStream.Position; while ElapsedSize > 0 do begin if ElapsedSize < BlockSize then CopySize := ElapsedSize else CopySize := BlockSize; TargetSource.CopyFrom(SourceSize, CopySize); ElapsedSize := SourceStream.Size - SourceStream.Position; // Здесь какие-то действия, например, модификация индикатора процесса end; . . .
Замечательные функции FileGetDate, FileSetDate, FileGetAttr, FileSetAttr выполняют очень важную работу, про которую не надо забывать: копируют дату создания файла и его атрибуты. Сейчас мы не будем углубляться в особенности файловой системы NTFS, в которой есть дата последней модификации файла и расширенные атрибуты, поскольку приведённого кода нам вполне для наших целей хватит.
Примечание:
Корректное копирование предполагает, что у целевого файла обязательно устанавливается флаг Archive. Я не буду углуляться в то, зачем это делается, тем более, что в нашем случае этого делать не обязательно.
Тем не менее, если вы хотите реализовать полноценную операцию копирования, не забудьте про эту маленькую особенность.
Вот и всё, Удачи!
Добавил(а): Denismen | Дата: 2014-01-25 | |
|
Hello I am using the CopyFile
function in Delphi 5. But the file is not getting copied to destination. I am not able to see error also. What is the best way to know why CopyFile
is failing?
if CopyFile(source, dest, false) then
ShowMessage('Success')
else
ShowMessage('Error');
I am getting displayed error always.
Jerry Dodge
26.9k31 gold badges155 silver badges328 bronze badges
asked Aug 9, 2012 at 19:12
7
If the function fails you can get extended error information, calling the GetLastError
method or use the RaiseLastOSError method.
Check this sample
try
If copyFile(source , dest,false) then
ShowMessage('Success')
else
RaiseLastOSError;
except on E: Exception do
showMessage(Format('Error executing copyFile %s',[E.Message]));
end;
answered Aug 9, 2012 at 19:19
RRUZRRUZ
135k20 gold badges356 silver badges483 bronze badges
6