Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 6

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 5

Познаем сами, помогаем другим...
Обсуждаем вопросы, не связанные с юникоидными версиями Delphi - для этого есть соответствующая тема (см. ссылки ниже).

Правила топика:
    Прежде чем спрашивать:
  1. Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
  2. Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
  3. Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
  4. Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
  5. Желательно указывать версии используемого компилятора и операционной системы.
    Прежде чем отвечать:
  1. Если не можете помочь, не мешайте.
  2. Если уж вы отвечаете на вопрос, давайте ответ по сути.
  3. Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
  4. Задавайте дополнительные вопросы, чтобы получить больше информации.
  • Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.  
  • Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].

     
    И старайтесь, чтобы ваш код не попал сюда

  • Всего записей: 3928 | Зарегистр. 29-07-2003 | Отправлено: 05:13 19-05-2010 | Исправлено: data man, 02:45 31-12-2010
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    Сразу скажу - делать так, идея в корне неверная. После переименования сбивается список файлов, в итоге получишь ерунду.
    Правильно - вначале получаешь список файлов/каталогов с помощью рекурсии, потом пробегаешься по списку и переименовываешь.  
     

    Спасибо за помощь, если есть время, не мог бы показать как это осуществить в данной функции? Был бы при много благодарен!

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 03:19 17-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Почему то
    MoveFile(PChar(StartDir + SearchRec.Name), '0.9.21.0.3');
    и
    RenameFile(StartDir + SearchRec.Name, '0.9.21.0.3');  
    не переименовывает...

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 06:50 17-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Alexzzy

    Цитата:
    Делается проще. Как то так.

    Ну, изначально была задача: найти конкретную папку(папки). В этом варианте маска не нужна, а двойная рекурсиядвойной цикл - тем более.
     
    GRom V

    Цитата:
    RenameFile(StartDir + SearchRec.Name, '0.9.21.0.3');  
    не переименовывает...

    Это функция. Посмотри код ошибки и узнаешь - почему.

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 07:33 17-01-2018 | Исправлено: XenoZ, 14:26 17-01-2018
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    GRom V

    Цитата:
    Спасибо за помощь, если есть время, не мог бы показать как это осуществить в данной функции?

    Дельфи под рукой нет, но внутри ДАННОЙ функции это сделать нельзя (неправильно).  
    Загоняете все это в TList, потом пробегаетесь по его элементам и уже им делаете Rename.
    Что то типа

    Код:
     
    for i:=0 to List.Items.Count - 1 do begin
      MyFolder := List.Items[i];
      RenameFile(MyFolder, 'new folder');
    end;
     

     
    А вообще для начала для теста попробуйте сделать так
    RenameFile(StartDir + SearchRec.Name, StartDir + '0.9.21.0.3');  
    то есть указывая полный путь и к исходной папке, и к результирующей.
    Либо вообще проверить, как корректно прописать
    RenameFile('полный путь к старой папке', 'полный путь к папке с новым именем');


    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3928 | Зарегистр. 29-07-2003 | Отправлено: 09:00 17-01-2018 | Исправлено: ShIvADeSt, 09:01 17-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    А вообще для начала для теста попробуйте сделать так
    RenameFile(StartDir + SearchRec.Name, StartDir + '0.9.21.0.3');  
    то есть указывая полный путь и к исходной папке, и к результирующей.  

    Да, так все работает! А почему нельзя внутри функции - ну будет находить и сразу переименовывать.?
    Так же проще?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 09:14 17-01-2018
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    GRom V

    Цитата:
    Да, так все работает! А почему нельзя внутри функции - ну будет находить и сразу переименовывать.?  

    Будет сбиваться структура каталога, который в данный момент обходится. То есть ваш каталог был н-р 3, а может стать 7 в папке. В итоге, у Вас не будет гарантии, что программа корректно переименовала нужные файлы.
    Я так один раз влетел, долго не мог понять почему не все записи обрабатываются. А программа честно брала следующую запись, так как не знала, что порядок изменился.

    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3928 | Зарегистр. 29-07-2003 | Отправлено: 09:19 17-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    Будет сбиваться структура каталога, который в данный момент обходится. То есть ваш каталог был н-р 3, а может стать 7 в папке. В итоге, у Вас не будет гарантии, что программа корректно переименовала нужные файлы.
    Я так один раз влетел, долго не мог понять почему не все записи обрабатываются. А программа честно брала следующую запись, так как не знала, что порядок изменился.

    Я пробовал после:
    List.Add('DIR: ' + StartDir + SearchRec.Name + '\');
     
    ставить: showmessage(StartDir + SearchRec.Name);
    И у меня после каждой найденной папки появлялось сообщение из чего я сделал вывод что если вставить переименование - после каждой найденной папки тут же будет переименовываться.
     
    все вроде работает единственное я не могу в RenameFile(StartDir + SearchRec.Name, StartDir + '0.9.21.0.3');    вместо '0.9.21.0.3' вставит Eiit2.Text - ругается
     
    Добавлено:
    А вот это:
    for i:=0 to List.Items.Count - 1 do begin
      MyFolder := List.Items[i];
      RenameFile(MyFolder, 'new folder');
    end;  
    Можно при нажатии кнопки сделать?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 09:29 17-01-2018
    Alexzzy

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    XenoZ

    Цитата:
    Ну, изначально была задача: найти конкретную папку(папки). В этом варианте маска не нужна, а двойная рекурсия - тем более.

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

    Всего записей: 1450 | Зарегистр. 10-07-2013 | Отправлено: 11:16 17-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    В общем сделал так:
    procedure ScanDir(StartDir, Mask, Mask2: string; List: TStrings);
    var
      SearchRec: TSearchRec;
    begin
      StartDir := IncludeTrailingPathDelimiter(StartDir);
     
      {поиск по маске в текущей директории}
      if FindFirst(StartDir + Mask, faAnyFile, SearchRec) = 0 then
      begin
        repeat
          if (SearchRec.Attr and faDirectory) = faDirectory then
          begin
            if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
              List.Add('DIR: ' + StartDir + SearchRec.Name + '\');
              //////////////////////////////////////////////////////////////////////////
              RenameFile(StartDir + SearchRec.Name, StartDir + Mask2);
          end;
          end
          else
            List.Add('FILE: ' + StartDir + SearchRec.Name);
        until FindNext(SearchRec) <> 0;
        FindClose(SearchRec);
      end;
     
      {рекурсивный обход всех поддиректорий}
      if FindFirst(StartDir + '*', faDirectory, SearchRec) = 0 then
      begin
        repeat
          if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then
            ScanDir(StartDir + SearchRec.Name, Mask, Mask2, List);
        until FindNext(SearchRec) <> 0;
        FindClose(SearchRec);
      end;
          end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ListBox1.Items.Clear;
      ScanDir(Label2.Caption, Edit1.Text, Edit2.Text, ListBox1.Items);
      Label1.Caption := 'Найдено' + ' ' + IntToStr(ListBox1.Items.Count);
      ScanDir(Label2.Caption, Edit2.Text, '', ListBox2.Items);
      Label3.Caption := 'переименовано' + ' ' + IntToStr(ListBox2.Items.Count);
    end;
     
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      chosenDirectory : string;
    begin
      if SelectDirectory('Выберите каталог', '', chosenDirectory)
      then
      Label2.Caption:= chosenDirectory
      else ShowMessage('Выбор каталога прервался');
    end;
     
    Вроде работает, и во втором листе видно результат... Так пойдет?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 14:20 17-01-2018 | Исправлено: GRom V, 14:21 17-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Alexzzy

    Цитата:
    Что-то я двойной рекурсии нигде не заметил.

    Пардон, не то ляпнул спросонья. Исправился.
    Имел в виду двойной цикл, конечно. Твой вариант, в принципе, универсален, но для данной задачи он избыточен.
     
    ShIvADeSt

    Цитата:
    Дельфи под рукой нет, но внутри ДАННОЙ функции это сделать нельзя (неправильно).

    Ммм... В свое время писал программку с обработкой/переименованием файлов именно внутри, никаких проблем не заметил.
     

    Цитата:
    Либо вообще проверить, как корректно прописать
    RenameFile('полный путь к старой папке', 'полный путь к папке с новым именем');

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

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 14:41 17-01-2018
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    XenoZ

    Цитата:
    В свое время писал программку с обработкой/переименованием файлов именно внутри, никаких проблем не заметил.

    Ну мое предположение проверить легко.
    Сделайте 10 файлов с именами
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    запустите рекурсию с переименованием путем дописывания 1 вначале имени. По идее должно будет получиться так
    11
    12
    ...
    110
    В реальности получится немного другая картина. Останется ряд файлов со старыми именами, и будет несколько файлов с несколькими 1 вначале.

    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3928 | Зарегистр. 29-07-2003 | Отправлено: 04:11 18-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    ShIvADeSt

    Цитата:
    Ну мое предположение проверить легко.

    Проверил... Наглядно!
    Таки да, поиском нужно только формировать список, а переименование - отдельным циклом.

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 14:52 18-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    И снова доброе время.
    Все таже функция:
    procedure ScanDir(StartDir, Mask, Mask2: string; List: TStrings);
    var
      SearchRec: TSearchRec;
    begin
      StartDir := IncludeTrailingPathDelimiter(StartDir);
     
      if FindFirst(StartDir + Mask, faAnyFile, SearchRec) = 0 then
      begin
        repeat
          if (SearchRec.Attr and faDirectory) = faDirectory then
          begin
            if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
              //List.Add('DIR: ' + StartDir + SearchRec.Name + '\');
              List.Add('' + StartDir + SearchRec.Name + '\');
              //////////////////////////////////////////////////////////////////////////
              RenameFile(StartDir + SearchRec.Name, StartDir + Mask2);
          end;
          end
          else
            //List.Add('FILE: ' + StartDir + SearchRec.Name);
            List.Add('' + StartDir + SearchRec.Name);
            RenameFile(StartDir + SearchRec.Name, StartDir + Mask2);
        until FindNext(SearchRec) <> 0;
        FindClose(SearchRec);
      end;
     
      if FindFirst(StartDir + '*', faDirectory, SearchRec) = 0 then
      begin
        repeat
          if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then
            ScanDir(StartDir + SearchRec.Name, Mask, Mask2, List);
        until FindNext(SearchRec) <> 0;
        FindClose(SearchRec);
      end;
          end;
     
    Есть один недостаток - в листбокс строки появляются только когда сканирование завершено а во время выполнения как будто висяк. Как сделать чтоб строка с найденным файлом, при сканировании, появлялась сразу?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 14:41 19-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    GRom V

    Цитата:
    во время выполнения как будто висяк.

    Application.ProcessMessages;

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 16:03 19-01-2018
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    XenoZ
    Только тогда всем формам Enable := False надо делать, а то можно еще что-нибудь запустить до окончания поиска.

    Всего записей: 2181 | Зарегистр. 24-05-2007 | Отправлено: 17:25 19-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    Application.ProcessMessages;

    ее надо в начале функции вставить?
     
    Добавлено:
    Да и еще... как остановить процесс поиска?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 18:19 19-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    GRom V

    Цитата:
    ее надо в начале функции вставить?

    Ее надо вставить в цикл.
     

    Цитата:
    как остановить процесс поиска?

    Добавь глобальный флаг и подключи его проверку, к примеру, в until ..
    Установку флага повесь на кнопку.

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 18:47 19-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    Ее надо вставить в цикл.  

    Прошу прощения за тупой вопрос - можно конкретно? Я ставил сюда и все вроде работает:
    procedure ScanDir(StartDir, Mask, Mask2: string; List: TStrings);
    var
      SearchRec: TSearchRec;
    begin
      StartDir := IncludeTrailingPathDelimiter(StartDir);  
      Application.ProcessMessages;  
     
     
     
    Добавлено:

    Цитата:
    Добавь глобальный флаг и подключи его проверку, к примеру, в until ..
    Установку флага повесь на кнопку.

    Можно пример остановки?

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 01:46 20-01-2018 | Исправлено: GRom V, 02:47 20-01-2018
    XenoZ



    Gold Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    GRom V

    Цитата:
    можно конкретно?

    В твоем коде два цикла repeat .. until.
     

    Цитата:
    Можно пример остановки?

    Примерно так...

    ----------
    А оно мне надо?..

    Всего записей: 5007 | Зарегистр. 29-03-2006 | Отправлено: 10:09 20-01-2018
    GRom V

    Full Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Цитата:
    В твоем коде два цикла repeat .. until.  

     
    т.е. так?
     
    begin
        repeat
          Application.ProcessMessages
          if (SearchRec.Attr and faDirectory) = faDirectory then
          begin
            if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
              List.Add('' + StartDir + SearchRec.Name + '\');  
             

    Всего записей: 464 | Зарегистр. 31-10-2006 | Отправлено: 12:01 20-01-2018
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 6

    Имя:
    Пароль:
    Сообщение

    Для вставки имени, кликните на нем.

    Опции сообщенияДобавить свою подпись
    Подписаться на получение ответов по e-mail
    Добавить тему в личные закладки
    Разрешить смайлики?
    Запретить коды


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.Board
    © Ru.Board 2000-2018

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru