Определить размер группы файлов

 
0
 
C++
ava
denisminb | 21.01.2013, 00:00
Добрый вечер, помогите пожалуйста реализовать до конца задачу.
осталось, определить:
-средний размер для каждой группы файлов (группировать по расширению и отдельной строкой - для всех) - рекурсивно по всей папке.


Вычисляю размер файлов,папок,количество- так:

void DirSize(AnsiString Folder,double &Size,double &fCount,double &folCount)
  {
  // Функция записывает в параметры:
  // Size - размер папки в байтах
  //fCount - общее количество файлов в папке
  //folCount - общее количество подпапок в папке

  TSearchRec SR;
  // Проверяем, заканчивается ли путь к папке на \,
  // если да, то удаляем его
  if(Folder[Folder.Length()] == '\\')
     Folder.SetLength(Folder.Length()-1);
  // Делаем первый поиск
  if(FindFirst(Folder+"\\*.*",faAnyFile,SR) == 0)
   do
      {   //Если то что мы нашли не является обратными ссылками...
         if(SR.Name != "." &&  SR.Name != "..")
         {
            
            if((SR.Attr & faDirectory)!=0)
               {
                 DirSize(Folder+"\\"+SR.Name,Size,fCount,folCount);
                  folCount++;
               }
            else
               {
                  
                  Size = Size + SR.Size;
                  fCount++;
               }
         }
      }
   while(FindNext(SR)==0);
    FindClose(SR);
  }



До конца,так и не могу решить задачу
Kommentare (12)
ava
volatile | 20.01.2013, 23:27 #
Цитата (denisminb @  20.1.2013,  23:00 findReferencedText)
средний размер для каждой группы файлов (группировать по расширению 

Это вам нужен какой-то массив.
В качестве оного, имхо, больше всего подойдет std::map, где ключами будут строки с расширением файла, а значениями - размер.
ava
NoviceF | 21.01.2013, 08:43 #
 smile хехе.. тестовое задание Esignal? Пол года назад мне так и не удалось организовать параллельное выполнение гуи и логики (не было знаний и время поджимало). Рекомендую вам обратить своё внимание в первую очередь на это, с потоками дружите?
ava
denisminb | 21.01.2013, 09:28 #
Цитата (NoviceF @ 21.1.2013,  08:43)
smile хехе.. тестовое задание Esignal? Пол года назад мне так и не удалось организовать параллельное выполнение гуи и логики (не было знаний и время поджимало). Рекомендую вам обратить своё внимание в первую очередь на это, с потоками дружите?

да,esignal.
с потоками средне дружу.
Вы в контору прошли?
ava
denisminb | 21.01.2013, 10:55 #
А без потоков как решить?

später ergänzt:
volatile,
А можете на не больщом примере показать,что имели ввиду?
ava
NoviceF | 21.01.2013, 12:08 #
Цитата (denisminb @  21.1.2013,  10:28 findReferencedText)
Вы в контору прошли? 

Нет.. к сожалению или к счатью, пока не знаю smile)

Цитата (denisminb @  21.1.2013,  11:55 findReferencedText)
А без потоков как решить?

Известными мне способами никак.. читайте в конце задания, что-то типа "интерфейс пользователя не должен замирать... бла бла бла", вот тут и нужна будет многопоточность. Я как смог сделал все пункты, кроме этого.. ну и ещё у меня русские пути в файловой системе не понимала программа, это, я считаю, была проблема Qt, с аглийскими путями всё прекрасно работало и даже гуи был, только в одном потоке с логикой.
ava
NoviceF | 21.01.2013, 12:30 #
Цитата (denisminb @  21.1.2013,  11:55 findReferencedText)
А можете на не больщом примере показать,что имели ввиду? 


не знаю насколько это показательно.. и сделать конечно можно намного красивее и правильнее, но тем не менее просто покажу что когда-то делал я :)

Сначала проходим по всем путям нужной нам директории, и средствами Qt, а точнее вот такого класса QFileInfoList, пути сохраняем в QStringList datalist.
Проходим по QStringList datalist, выбирая только расришения, сохраняем их в set<std::string>.

Даём на вход функции map вида std::map<std::string, vector<std::string> > (тут у нас в итоге должны содержаться данные в виде: ключ - расширение файла, значения - пути к файлам) и set<std::string> содержащий расширения.


typedef std::vector<std::string> stringlist;
typedef std::map<std::string, stringlist> maplist;

void listModel::initMapList(maplist &maplst, std::set<std::string> extlist,
        QStringList datalist) {
    maplst.clear();
    for (std::set<std::string>::iterator it = extlist.begin(); it != extlist.end();
            ++it) maplst[*it];
    for (QStringList::iterator it = datalist.begin(); it != datalist.end(); ++it) {

        size_t found;
        std::string ext;
        found = (*it).toStdString().find_last_of('.');
        ext = (*it).toStdString().substr(found);
        std::transform(ext.begin(), ext.end(), ext.begin(), tolower);

        maplst[ext].push_back((*it).toStdString());
    }

}


пысы, только не нужно пинать меня за стиль и приёмы, по сути был мой первый опыт что-то писать самостоятельно smile
ava
volatile | 21.01.2013, 13:04 #
Цитата (denisminb @  21.1.2013,  10:55 findReferencedText)
можете на не больщом примере показать,что имели ввиду? 

создать ассоциативный контейнер, скажем

std::map <std::string, long long> groups;

передать его по ссылке, в вашу функцию

void DirSize(,..., std::map <std::string, long long> & groups)

в функции выделить расширение очередного файла в строковую переменную, скажем ext;
т.е. для для "prog.exe", ext должно быть "exe"
Ну и прибавлять размеры в группы:

   groups [ext] += SR.Size; 

после возврата, в массиве groups будут суммы размеров файлов, сгруппированных по расширению.

***еще, пожалуй, std::string и AnsiString смешивать в одной програаме не стоит. Так что вибирайте сами.

 smile 
Цитата (denisminb @  21.1.2013,  09:28 findReferencedText)
Вы в контору прошли? 

если не секрет вы о какой конторе?

später ergänzt:
код NoviceF, не видел когда писал
ava
NoviceF | 21.01.2013, 13:20 #
Цитата (volatile @  21.1.2013,  14:04 findReferencedText)
если не секрет вы о какой конторе?


вот об этой eSignal http://hh.ru/employer/116364
ava
denisminb | 21.01.2013, 13:57 #
Цитата (NoviceF @ 21.1.2013,  12:30)




Цитата (denisminb @  21.1.2013,  11:55 \\"findReferencedText\\")
А можете на не больщом примере показать,что имели ввиду? 




не знаю насколько это показательно.. и сделать конечно можно намного красивее и правильнее, но тем не менее просто покажу что когда-то делал я smile



Сначала проходим по всем путям нужной нам директории, и средствами Qt, а точнее вот такого класса QFileInfoList, пути сохраняем в QStringList datalist.

Проходим по QStringList datalist, выбирая только расришения, сохраняем их в set<std::string>.



Даём на вход функции map вида std::map<std::string, vector<std::string> > (тут у нас в итоге должны содержаться данные в виде: ключ - расширение файла, значения - пути к файлам) и set<std::string> содержащий расширения.





typedef std::vector<std::string> stringlist;

typedef std::map<std::string, stringlist> maplist;



void listModel::initMapList(maplist &maplst, std::set<std::string> extlist,

        QStringList datalist) {

    maplst.clear();

    for (std::set<std::string>::iterator it = extlist.begin(); it != extlist.end();

            ++it) maplst[*it];

    for (QStringList::iterator it = datalist.begin(); it != datalist.end(); ++it) {



        size_t found;

        std::string ext;

        found = (*it).toStdString().find_last_of('.');

        ext = (*it).toStdString().substr(found);

        std::transform(ext.begin(), ext.end(), ext.begin(), tolower);



        maplst[ext].push_back((*it).toStdString());

    }



}





пысы, только не нужно пинать меня за стиль и приёмы, по сути был мой первый опыт что-то писать самостоятельно smile

Да.....Qt я не знаю. Это точно.
Надо по другому думать
ava
NoviceF | 21.01.2013, 14:30 #
Цитата (denisminb @  21.1.2013,  14:57 findReferencedText)
Да.....Qt я не знаю. Это точно.

Надо по другому думать 


А GUI на чём планировал делать? Если MFC или подобные порождения MS, там свои функции есть для всех этих дел.
ava
volatile | 21.01.2013, 18:09 #
Цитата (denisminb @  21.1.2013,  13:57 findReferencedText)
Qt я не знаю

Qt здесь знать не нужно. Нужно знать std::map.
Это стандартный контейнер.
я вам написал без Qt, нужно только правильно рассавить строчки что я привел, в ваш код.
(и я как-то не вижу с вашей стороны попыток, это сделать)

ava
Dem_max | 22.01.2013, 08:34 #
Чтобы писать многопоточные приложения работающие с GUI под windows на QT нужно постараться, так как сигналы в QT организованны так что предусматривают блокировку потока GUI.
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden