Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Копирование файлов из вложенных директорий


Автор: larinva 25.9.2009, 10:36
Всем привет пишу прогу в ней есть функция копирование (т.е по заданной дате происходит поиск файлов в определенной папке с подкаталогами после чего найденные файлы, если такие есть заносится в ListBox, и одновременно эти файлы должны быть скопированы в заданную папку. С добавлением в ListBox все нормально, а вот копирование не идет а точнее копируются файлы только из корневой папки а вот из подкаталогов нет вот мой листинг подскажите где где не так или подправьте его, плиз
Код

procedure TForm1.CopyDirectory(path1, path2: string);
var f: TSearchRec;
  i,s: integer;
  ladd:boolean;
  TBegin:integer;
 begin
// смена каталога чтобы не нужно было задавать полный путь к файлу
ChDir(path1);
// начало поиска
  i:= FindFirst('*.*', faAnyFile, f);
while i=0 do
  begin
  if (f.Name<>'.') and (f.name<>'..') then
  begin
  ladd:=true;
// проверяем атрибуты файла и стоит ли галочка на (включить влаженные папки)
  if ((f.Attr and faDirectory)<>0) and CBInclude.Checked then
// поиск во вложенной папке
    CopyDirectory(path1+f.Name, f.Name)
      else
      begin
        if (f.Attr and faDirectory)=0 then
         begin
// проверка даты
          case RGData.ItemIndex of
          0:TBegin:=DateTimeToFileDate(Date);
          1: if f.Time>DateTimeToFileDate(DateTimePicker2.Date) then
            TBegin:=f.Time+1000
            else TBegin := DateTimeToFileDate(DateTimePicker1.Date);
            end;
          ladd:= f.Time>= TBegin;
         end;
         if ladd then
   begin
// занесение в лист бокс имена файлов и копируем
   s:=ListBox1.Items.add(f.Name);
//копирование в папку 
  CopyFile(pchar(path1+f.Name), pchar(path2+f.Name), true);
    end;
  end;
  end;
// продолжение поиска
 i:= FindNext(f);
end;
  FindClose(f);
// возврат в предыдущий каталог
  ChDir('..');
 end;


Автор: kami 25.9.2009, 20:23
Цитата(larinva @  25.9.2009,  10:36 Найти цитируемый пост)
//копирование в папку   CopyFile(pchar(path1+f.Name), pchar(path2+f.Name), true);

1.посмотри в отладчике, что получается при суммировании Path1и2+name (в смысле, не забывается ли "\".
2. А вообще - надо начинать с того, что возвращает CopyFile
как-то так:
Код

if not CopyFile(...) then
  raiseLastOSError;

Автор: ~FoX~ 25.9.2009, 22:08
larinva, Создавать директории надо прежде чем в них файлы копировать... Я например сначала создаю структуру дерева, а потом копирую...


Автор: Keeper89 25.9.2009, 23:31
План:
1) Получаем список нужных файлов (по дате);
2) Создаем директории (при необходимости) и копируем.

Вот рабочий примерчик (проект прикрепил):
Код

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    DateTimePicker1: TDateTimePicker;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure SearForFilesWithSpecDate(const curPath: AnsiString;
                                   curDate: TDateTime;
                                   var filesList: TStringList);
var
  SearchRec: TSearchRec;
begin

  if FindFirst(curPath + '*.*', faAnyFile, SearchRec) = 0 then
  begin
    repeat
    Application.ProcessMessages;
      if ((SearchRec.Attr and faDirectory) <> faDirectory) then
      begin
        if (FileDateToDateTime(SearchRec.Time) > curDate) then
          filesList.Add(curPath + SearchRec.Name)
      end
      else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then
      begin
        SearForFilesWithSpecDate
          (IncludeTrailingPathDelimiter(curPath + SearchRec.Name),
           curDate, filesList);
      end;
    until FindNext(SearchRec) <> 0;
    FindClose(SearchRec);
  end;
end;

procedure CopyFiles(filesList: TStringList;
                    const dest: AnsiString;
                    const curPathLength: Word);
var
  i: Integer;
  curDir, curFile: AnsiString;
begin
  for i := 0 to filesList.Count - 1 do
  begin
    // Строим новые директории
    curFile := dest + Copy(filesList[i], curPathLength + 1,
                           Length(filesList[i]));
    curDir := ExtractFileDir(curFile);
    if Not FileExists(curDir) then
      ForceDirectories(curDir);
    if CopyFile(PChar(filesList[i]), PChar(curFile), False) then
      Form2.ListBox1.Items[i] := Form2.ListBox1.Items[i] + ' (скопирован)';
  end;
    
end;


procedure TForm2.Button1Click(Sender: TObject);
var
  filesList: TStringList;
  curPath: AnsiString;
begin

  filesList := TStringList.Create();

  Screen.Cursor := crHourGlass;
  try
    curPath := IncludeTrailingPathDelimiter(Edit1.Text);
    SearForFilesWithSpecDate(curPath, DateTimePicker1.Date, filesList);
    ListBox1.Items.Assign(filesList);
    CopyFiles(filesList, IncludeTrailingPathDelimiter(Edit2.Text),
              Length(curPath));
  finally 
    Screen.Cursor := crDefault;
    filesList.Free;
  end;
end;

end.


Автор: bems 26.9.2009, 23:55
почему бы не завязать с изобретением велосипедов и не использовать SHFileOperation?

Автор: larinva 28.9.2009, 13:14
Хороший пример от Keeper89а а вот как сделать чтобы при копировании директории не создавались а валилось все в одну папку очень прошу, а чёт у меня полный тупняк smile 

Автор: ~FoX~ 28.9.2009, 15:09
Код

  curDir := 'c:\куда кладем';


Автор: larinva 28.9.2009, 15:19
Уважаемый ~FoX~  вы меня не поняли нужно чтобы все найденные файлы складывались в одну директорию а не по папкам в этой директории


Автор: larinva 28.9.2009, 16:10
Всем спасибо внес некоторые изменения в своей функции стала копировать как нужно и куда нужно теперь другая проблема к имени файла добавляется название директории в которой он лежал как это удалить smile 

Автор: Keeper89 28.9.2009, 17:26
Заменить
Код

filesList.Add(curPath + SearchRec.Name)

на 
Код

filesList.Add(SearchRec.Name)

Автор: ~FoX~ 29.9.2009, 09:11
larinva, Тебя то я понял....код просто не внимательно прочел  smile 

Автор: larinva 5.10.2009, 16:29
большое спасибо тебе ~FoX~ smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)