C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 Здравствуйте, гость ( Вход | Регистрация )   Скачать форум | Поиск по Форуму | Участники | Помощь
 Поиск по:   сайтy   
   архиву форума   
  ОтветитьНовая темаНовый опрос
FindFirst, путь к файлу
« предыдущая тема | следующая тема » Подписаться на тему | Отправить тему на E-mail | Распечатать тему
Лена
Отправлено: 11.11.2006, 14:50 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Написала код, который ищет самый новый файл по дате. Подскажите, как его подправить, чтобы в переменную S записывался полный путь к этому файлу. Например, C:\Foto\1.gif где 1.gif это самый новый по дате создания файл, на диске С.
Что-то кручу - кручу, а получается ерунда. smile.gif

CODE

void LookInDir(AnsiString DirName,   TDateTime D)
{

 TSearchRec sr;
 AnsiString S;
 for(int r=FindFirst(DirName+"\\*.*",faDirectory,sr);!r;r=FindNext(sr))
   if((sr.Attr&faDirectory) && (sr.Name!="." && sr.Name!=".."))
     LookInDir(DirName+"\\"+sr.Name,  0);
 FindClose(sr);
 for(int r=FindFirst(DirName+"\\*.*",faDirectory,sr);!r;r=FindNext(sr))
       if (FileDateToDateTime(sr.Time) > D)
       {
        D = FileDateToDateTime(sr.Time);
        S = sr.Name;
       }
     FindClose(sr);

 Form1->ListBox1->Items->Add(S);//как тут сформировать путь к файлу?

}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  LookInDir("C:\\Foto", 0);
}

 
Послать сообщение E-mail адрес  Top
__Cheat3r
Отправлено: 11.11.2006, 15:33 Цитировать


Станционный диспетчер


Группа: Участник
Сообщений: 110
Пользователь № 1443
Регистрация: 02.01.06



или я не понял, или
CODE
Form1->ListBox1->Items->Add(DirName+"\\"+S);//как тут сформировать путь к файлу?
 
Послать сообщение E-mail адрес  Top
Лена
Отправлено: 12.11.2006, 11:01 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Мне нужно чтобы в ListBox1 попадала только первая запись (см. рисунок). При этом код должен всегда находить самый новый файл на диске, не взирая на то, где он лежит в корне или в других папках.



Присоединить изображение

Присоединить изображение

 
Послать сообщение E-mail адрес  Top
beginner
Отправлено: 12.11.2006, 16:38 Цитировать


Дежурный стрелочник


Группа: Участник
Сообщений: 44
Пользователь № 2548
Регистрация: 09.10.06



Для того, чтоб попала только одна запись,
нужно передавать время, как ссылку на переменной, и
S тоже передавать как AnsiString &, т.е. ф-ия должна бы иметь
вид

void LookInDir(AnsiString DirName, TDateTime &D, AnsiString &S)

И из ф-ии нужно удалить

ListBox1->Items->Add(S);
CODE
void TForm1::LookInDir(AnsiString DirName, TDateTime &D, AnsiString &S)
{
 TSearchRec sr;
 for(int r=FindFirst(DirName+"\\*.*",faDirectory,sr);!r;r=FindNext(sr))
 {
   if((sr.Name == ".")||(sr.Name==".."))continue;
   if(sr.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
     LookInDir(DirName + "\\" + sr.Name, D, S);
   else if(FileDateToDateTime(sr.Time) > D)
   {
     D = FileDateToDateTime(sr.Time);
     S = DirName + "\\" + sr.Name;
   }
 }
 FindClose(sr);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TDateTime dt = 0;
 AnsiString S = "";
 LookInDir("C:\\Foto", dt, S);
 if(S!="")
   ListBox1->Items->Add(S);
}


Отредактировано beginner - 12.11.2006, 17:56
 
Послать сообщение E-mail адрес  Top
Лена
Отправлено: 13.11.2006, 11:10 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Cпасибо!
Передача по ссылке, все сделала как надо. smile.gif

P.S.
Скажите как подправить цикл, на случай если папок очень много?
Чтобы приложение отвечала на запросы добавила в конце цикла: Application->ProcessMessages(); Однако если папок много (например корень диска С), то почем то находится не самый новый файл.

Отредактировано Лена - 13.11.2006, 16:49
 
Послать сообщение E-mail адрес  Top
Лена
Отправлено: 13.11.2006, 17:02 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Кажется нашла. Все время находиться стандартный файл от Windows: C:\Documents and Settings\All Users\Documents\Ico\Icons2\Zamok256.ICO и у него почему-то дата изменения 2015 год. Не понятно. ohmy.gif

P.S. Посмотрела в этой папке у всех стоит 2015 год. wizard.gif
(Windows XP SP2 Media Edition)
На диске D нормально ищет.

Отредактировано Лена - 13.11.2006, 17:06

Присоединить изображение

Присоединить изображение

 
Послать сообщение E-mail адрес  Top
Konstantine
Отправлено: 13.11.2006, 17:39 Цитировать


Мастер участка


Группа: Модератор
Сообщений: 545
Пользователь № 790
Регистрация: 17.08.04



ИМХО в данном случае стоило бы сделать переменную D статической. именно это и ест ьобласть применения статики - в рекурсивных функциях

--------------------
Нет ничего более постоянного чем временное...
 
Послать сообщение E-mail адрес ICQ  Top
Лена
Отправлено: 13.11.2006, 17:59 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Cделала D статической.

Еще вопрос. Какое правильное условие добавить в цикл, чтобы в ListBox1 мог попасть только файл с раширением "*.jpg", "*.jpeg", "*.gif" а остальные просто отсекались?
 
Послать сообщение E-mail адрес  Top
Лена
Отправлено: 13.11.2006, 18:26 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Вот так придумала. Надежно?
CODE

void LookInDir(AnsiString DirName, TDateTime &D, AnsiString &S)
{
TSearchRec sr;
AnsiString EXE;
for(int r=FindFirst(DirName+"\\*.*",faDirectory,sr);!r;r=FindNext(sr))
{

  if((sr.Name == ".")||(sr.Name==".."))continue;
  if(sr.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
    LookInDir(DirName + "\\" + sr.Name, D, S);
  else if(FileDateToDateTime(sr.Time) > D)
  {
    D = FileDateToDateTime(sr.Time);
    EXE = sr.Name;
    int pos = EXE .Pos(".");
    EXE = Trim(EXE.SubString(pos+1,EXE.Length()));
    if (EXE == "jpeg" || EXE == "jpg" || EXE == "gif")
    {
     S = DirName + "\\" + sr.Name;
    }



  }
  Application->ProcessMessages();
}
FindClose(sr);
}

 
Послать сообщение E-mail адрес  Top
Shagg
Отправлено: 13.11.2006, 19:08 Цитировать


Дежурный стрелочник


Группа: Участник
Сообщений: 69
Пользователь № 1677
Регистрация: 07.06.06



Надежно, только расширение лучше получать функцией ExtractFileExt, т.к. для имен типа "111.tar.gz" или "my.picture.jpg" поиск по точке даст неверное расширение. Либо искать самую правую точку - тож вариант.
 
Послать сообщение E-mail адрес ICQ  Top
beginner
Отправлено: 13.11.2006, 19:39 Цитировать


Дежурный стрелочник


Группа: Участник
Сообщений: 44
Пользователь № 2548
Регистрация: 09.10.06



D = ...
нужно бы перенести в блок перед
S = ...
 
Послать сообщение E-mail адрес  Top
Лена
Отправлено: 14.11.2006, 11:29 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Окончательный вариант, значит получается такой:
CODE

void LookInDir(AnsiString DirName, TDateTime &D, AnsiString &S)
{
TSearchRec sr;
AnsiString EXE;
for(int r=FindFirst(DirName+"\\*.*",faDirectory,sr);!r;r=FindNext(sr))
{

  if((sr.Name == ".")||(sr.Name==".."))continue;
  if(sr.FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
    LookInDir(DirName + "\\" + sr.Name, D, S);
  else if(FileDateToDateTime(sr.Time) > D)
  {

    EXE = ExtractFileExt(sr.Name);

    if (EXE == ".jpeg" || EXE == ".jpg" || EXE == ".gif" || EXE == ".JPG"
               || EXE == ".JEPG" || EXE == ".GIF")
    {
     D = FileDateToDateTime(sr.Time);
     S = DirName + "\\" + sr.Name;
    }


  }
  Application->ProcessMessages();
}
FindClose(sr);
}



Вызов:
CODE

static TDateTime dt = 0;
               AnsiString S = "";
               //PathFolder - нужный путь
               LookInDir(PathFolder, dt, S);
               if(S!="")
                {
                  Form1->AdvPicture1->Picture->LoadFromFile(S);
                }


Когда папок много, хочу добавить прогресс бар, чтобы пользователь видел процесс поиска. Как правильно задать границы этого прогресс бара?
 
Послать сообщение E-mail адрес  Top
olegenty
Отправлено: 14.11.2006, 11:48 Цитировать


Ветеран


Группа: Модератор
Сообщений: 2412
Пользователь № 507
Регистрация: 13.02.04



никак, пока всё дерево не отсканируешь. так что просто можешь показывать текущий каталог в какой-нить Label + количество отсканеных.

--------------------
Управлять можно лишь тем, что можно измерить.
Восточная мудрость.
 
Послать сообщение E-mail адрес ICQ  Top
Лена
Отправлено: 14.11.2006, 12:03 Цитировать


Мастер участка


Группа: Участник
Сообщений: 501
Пользователь № 1148
Регистрация: 01.06.05



Понятно.

Подумаю, может еще такой вариант: какой-нибудь прогресс бар, который бы бегал как при загрузке Windows.

P.S.
Индификатор static пришлось убрать. Если вторично подсоединить флеш носитель во время выполнения программы, то картинка уже не находиться.
 
Послать сообщение E-mail адрес  Top
Doga
Отправлено: 14.11.2006, 12:20 Цитировать


Мастер участка


Группа: Участник
Сообщений: 575
Пользователь № 478
Регистрация: 16.01.04



Привет! smile.gif

QUOTE

может еще такой вариант: какой-нибудь прогресс бар, который бы бегал как при загрузке Windows

Однозначно - лучше не придумаешь!

А вообще, не так давно, я выкладывал пример НЕрекурсивной функции поиска файлов, может быть - пригодится... rolleyes.gif

http://www.rxlib.ru/forums/index.php?act=S...ad3cfd1b665795b

Самый последний пост...

Отредактировано Doga - 14.11.2006, 12:22

--------------------
Делай что должен - свершится, чему суждено...
 
Послать сообщение E-mail адрес Домашняя страница  Top
history
Отправлено: 28.11.2009, 10:04 Цитировать


Unregistered









Если поиск начинается с корневого каталого, то судя по твоему коду ты способна узнать размер файла которого ты в данный момент анализируешь. Таким образом зная занятое место на диске + сумму размеров уже проверенных файлов, ты способна будешь расчитать процент хода работы программы.
 
Top
15 ответов с: 11.11.2006, 14:50 Подписаться на тему | Отправить тему на E-mail | Распечатать тему

Back to Вопросы программирования в C++Builder
ОтветитьНовая темаНовый опрос