На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Копирование папки
    Я хочу откопировать папку. Для этого я использую копироание одного файла с помощью потока:

    http://www.sources.ru/delphi/files/copy_fi...in_thread.shtml

    1. Я создаю список файлов директории.
    2. По списку копирую каждый файл.

    Но после того, как программа откопировала ~2000 файлов, она вылетает с ошибкой. Что делать?
      Цитата
      Heretic2, 28.06.04, 16:56
      она вылетает с ошибкой
      C какой ошибкой? И где создаещ список файлов?
      Сообщение отредактировано: Bas -
        Покеж код, кстати зачем 2 темы?
          ExpandedWrap disabled
            uses
              ShellApi;
             
            function WorkFile(metod: Cardinal; FromFile,ToDir: string;
                                     const WndShow: Boolean = False;
                                     const Flags: Word = FOF_ALLOWUNDO or FOF_NOCONFIRMATION
                                    ): boolean;
            // Действия над файлами
            var
              FileOp: TSHFileOpStruct;
            //  Source: string;
            begin
              FillChar(FileOp, SizeOf(FileOp), #0);
              With FileOp do Begin
                if WndShow then Wnd:= GetActiveWindow;
                wFunc:= metod;
                FromFile:= FromFile + #0; // 07.09.03
                pTo:= pTo + #0;           // 29.06.04
                pFrom:= PChar(FromFile);
                pTo:= PChar(ToDir);
                fFlags:= Flags;
                fAnyOperationsAborted:= False;
                hNameMappings:= nil;
                lpszProgressTitle:= nil;
              end;
              result:= ShFileOperation(FileOp) = 0;
            end;
            // -----------------------------------------------------------------
            function acCopyFile(FromFile,ToDir: string;
                                     const WndShow: Boolean = False;
                                     const Flags: Word = FOF_ALLOWUNDO or FOF_NOCONFIRMATION
                                    ): boolean;
            // Копирование файла
            begin
              result:= WorkFile(FO_COPY, FromFile, ToDir, WndShow, Flags);
            end;
            // -----------------------------------------------------------------
            function acMoveFile(FromFile,ToDir: string;
                                const WndShow: Boolean = False;
                                const Flags: Word = FOF_ALLOWUNDO or FOF_NOCONFIRMATION
                               ): boolean;
            // Перемещение файла
            begin
              result:= WorkFile(FO_MOVE, FromFile, ToDir, WndShow, Flags);
            end;
            // -----------------------------------------------------------------
            function acDeleteFile(aFile: string;
                                  const WndShow: Boolean = False;
                                  const Flags: Word = FOF_ALLOWUNDO or FOF_NOCONFIRMATION
                                 ): boolean;
            // Удаление файла
            begin
              result:= WorkFile(FO_DELETE, aFile, '', WndShow, Flags);
            end;

          Пример использования
          ExpandedWrap disabled
            procedure TForm1.Button1Click(Sender: TObject);
            begin
              acCopyFile('e:\Prog\Delphi_Components\ZipTV_v4_for_Delphi6\*.*', 'E:\Temp\', False)
            end;
          Сообщение отредактировано: Alex-Co -
            Alex-Co,
            В WorkFile надо добавить еще:
            ExpandedWrap disabled
                  ToDir := ToDir + #0;
            до
            ExpandedWrap disabled
                  pTo:= PChar(ToDir);

            так как на параметр ToDir распространяется тоже правило что и на FromFile. Вот выдержка из MSDN:
            Цитата
            pTo
            Address of a buffer to contain the name of the destination file or directory. This parameter must be set to NULL if it is not used. Like pFrom, the pTo member is also a double-NULL terminated string and is handled in much the same way. However, pTo must meet the following specifications:
            Сообщение отредактировано: Петрович -
              Добавлю, спасибо
              Сообщение отредактировано: Alex-Co -
                1. Как решить мою проблему!(код вскоре выложу)

                2. В приведённом выше примере можно ли узнать на сколько процентов откопирован файл?
                Сообщение отредактировано: Heretic2 -
                  Надо юзать вот это lpszProgressTitle
                    и как "вот это" юзать
                      Всё-таки у меня осталось парочка вопросов.
                      1. Почему прога вылетает с ошибкой "Thread creation error: Недостаточно памяти для обработки команды", причём прога вылетает после копирования ~2000 файлов(любого размера)? :wall:
                      2. Есть ли какой нибудь другой метод копирования файла (без вызова виндового окна) , при этом методе (желательно) можно узнать на скольлко процентов файл откопирован? :(
                      3. Если нет других вариантов, то подскажите, как сделать так, чтобы Windows'овское окно не задавало вопросов, типа "Файл уже существует: переписать поверх"? :o


                      Вот код проги!!!

                      ExpandedWrap disabled
                        //-----------------------------------------------
                        //Copy files                                                
                        //-----------------------------------------------
                        constructor TCopyFile.Create(Src, Dest : String);
                        begin
                          IName := Src;
                          OName := Dest;
                          Percent := 0;
                          Start := Now;
                          FreeOnTerminate := True;
                          inherited Create(True);
                        end;
                         
                        procedure TCopyFile.Execute;
                        var
                          fi,fo       : TFileStream;
                          dod,did     : Integer;
                          cnt,max     : Integer;
                        begin
                          Start := Now;
                          try
                            fo := TFileStream.Create(OName, fmOpenReadWrite);
                            fo.Position:=fo.size;
                          except
                            fo := TFileStream.Create(OName, fmCreate);
                          end;
                          try
                            fi := TFileStream.Create(IName, fmOpenRead);
                            try
                              cnt:= fo.Position;
                              fi.Position := cnt;
                              max := fi.Size;
                              ToDo := Max-cnt;
                              Done := 0;
                              Repeat
                                dod := MB1;
                                if cnt+dod>max then dod := max-cnt;
                                if dod>0 then did := fo.CopyFrom(fi, dod);
                                cnt:=cnt+did;
                                if max<>0 then Percent := Round(Cnt/Max*100) else Percent:=100;
                                cursize:=cnt;
                                form3.Gauge1.Progress:=Percent;
                                form3.label5.caption:=inttostr(curprog);
                                form3.label6.caption:=inttostr(cursize);
                                form3.label7.caption:=inttostr(dirbytes);
                                if DirBytes<>0 then form3.Gauge2.Progress:=Round((curprog+cursize)/DirBytes*100);
                                Done := Done+did;
                                ToDo := Max;
                              until (dod=0) or (Terminated);
                            finally
                              fi.free;
                            end;
                          finally
                            fo.free;
                          end;
                        end;
                         
                        procedure CopyDir(FromDir, ToDir: string);
                        var
                          i : integer;
                          abc : Tcopyfile;
                          f: file of byte;
                        begin
                          form3.gauge1.Progress:=0;
                          form3.gauge2.Progress:=0;
                          cursize:=0;
                          curprog:=0;
                          createdir(ToDir);
                          for i:=0 to stnum-1 do begin
                            if FileExists(FromDir+form3.Memo1.Lines.Strings[i]) then begin
                                assignfile(f, ToDir+form3.Memo1.Lines.Strings[i]);
                                rewrite(f);
                                closefile(f);
                                form3.Gauge1.Progress:=0;
                                abc:=Tcopyfile.Create(FromDir+form3.Memo1.Lines.Strings[i], ToDir+form3.Memo1.Lines.Strings[i]);
                                abc.Execute;
                                application.ProcessMessages;
                                curprog:=curprog+cursize;
                                form3.Caption:=inttostr(i);//form3.Memo1.Lines.Strings[i];
                            end else begin
                                createdir(ToDir+form3.Memo1.Lines.Strings[i]);
                            end;
                          end;
                        end;
                         
                         
                         
                        function DirList(Dir, s:string):integer;
                        var
                           SearchRec : TSearchRec;
                           Separator : string;
                        begin
                           if Copy(Dir,Length(Dir),1)='\' then Separator := ''
                           else Separator := '\';
                           if FindFirst(Dir+Separator+'*.*',faAnyFile,SearchRec) = 0 then begin
                           if FileExists(Dir+Separator+SearchRec.Name) then begin
                              DirBytes := DirBytes + SearchRec.Size;      
                              stnum:=stnum+1;
                              form3.Memo1.Lines.Add(s+SearchRec.Name);
                           end
                           else
                              if DirectoryExists(Dir+Separator+SearchRec.Name) then begin
                                 if (SearchRec.Name<>'.') and (SearchRec.Name<>'..') then begin
                                    stnum:=stnum+1;
                                    form3.Memo1.Lines.Add(s+SearchRec.Name);
                                    DirSize(Dir+Separator+SearchRec.Name, s+SearchRec.Name+'\');
                                 end;
                              end;
                           while FindNext(SearchRec) = 0 do begin
                              if FileExists(Dir+Separator+SearchRec.Name) then begin
                                 DirBytes := DirBytes + SearchRec.Size;
                                 stnum:=stnum+1;
                                 form3.Memo1.Lines.Add(s+SearchRec.Name);
                              end
                              else
                                 if DirectoryExists(Dir+Separator+SearchRec.Name) then begin
                                    if (SearchRec.Name<>'.') and (SearchRec.Name<>'..') then begin
                                      stnum:=stnum+1;
                                      form3.Memo1.Lines.Add(s+SearchRec.Name);
                                      DirSize(Dir+Separator+SearchRec.Name,s+SearchRec.Name+'\');
                                    end;
                                 end;
                              end;
                           end;
                           FindClose(SearchRec);
                        end;
                         
                         
                         
                         
                        procedure TForm3.Button1Click(Sender: TObject);
                        var
                          fs, sp: string;  
                        begin
                              
                                fs:='d:\cs\';
                                sp:='D:\cs2\';
                                dirlist(fs,'');        
                                copydir(fs,sp);
                        end;
                        Цитата
                        Heretic2, 31.07.04, 23:48
                        (без вызова виндового окна)


                        Можно, усли указать флаг SH_SILENT.

                        Цитата
                        Heretic2, 31.07.04, 23:48
                        "Thread creation error: Недостаточно памяти для обработки команды"


                        Попробуй тоже сделать через WinExplorer, если он вылетает, значит придется ручками через TFileStream
                          Цитата
                          Heretic2, 31.07.04, 23:48
                          1. Почему прога вылетает с ошибкой "Thread creation error: Недостаточно памяти для обработки команды", причём прога вылетает после копирования ~2000 файлов(любого размера)?

                          Да потому, что ты неправильно используеш потоки. То как у тебя написано, это не правильно. У тебя нет никакой многопоточности :). Не надо самому вызываеть метод Execute потока!
                          a) Вместо вызова Execute, надо вызвать Resume - лишь тогда Execute будет запущена в отдельном потоке. И лишь тогда, по завершению Execute, поток бужет завершен, и объект потока будет разрушен. У тебя этого не происходит, поэтому наверное и памяти не хватает.
                          b) При правильном запуске потока (см. пункт a), внутри Execute НЕЛЬЗЯ напрямую обращаться к методам и свойствам объектов VCL (Gauge1, Label5, и пр.). Делать это нужно только через Synchronize.

                          В общем, почитай-ка сначала теорию, а именно, о том как писать многопоточные приложения на Delphi.

                          Цитата
                          Heretic2, 31.07.04, 23:48
                          2. Есть ли какой нибудь другой метод копирования файла (без вызова виндового окна) , при этом методе (желательно) можно узнать на скольлко процентов файл откопирован?
                          3. Если нет других вариантов, то подскажите, как сделать так, чтобы Windows'овское окно не задавало вопросов, типа "Файл уже существует: переписать поверх"?

                          Тебе же писали ShFileOperation. А по поводу "окон" и "вопросов", то почитай описание функции ShFileOperation, а именно, описание поля fFlags структуры SHFILEOPSTRUCT, передаваемой ей в качестве параметра.
                            И в дополнение - копирование файлов в потоках приводить к резкому замедлению работы, не считая того, что надо быть на ВЫ с потоками.
                            Напомню еще раз - для всех операций с файлами использовать ShFileOperation, кроме особых случаев.
                              Цитата
                              Anatoly Podgoretsky, 1.08.04, 12:14
                              надо быть на ВЫ с потоками.

                              :) Наверное, лучше на ТЫ :)

                              Цитата
                              Anatoly Podgoretsky, 1.08.04, 12:14
                              копирование файлов в потоках приводить к резкому замедлению работы

                              Думаю что да. Головки винчестера только и будут делать что носиться взад-вперед.
                              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0536 ]   [ 15 queries used ]   [ Generated: 24.05.24, 15:15 GMT ]