На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Рекурсивный поиск файлов заполняет не выгруженный пул памяти Си WINAPI , Рекурсивный поиск файлов заполняет не выгруженный пул памяти Си WINAPI
    Приветствую,джентельмены.
    Пытаюсь выполнить поиск файлов на локальном диске,включая файлы во всех каталогах.
    Использовал для этого примеры,которые можно найти в интернете.
    Файлы находит,с этим проблем нет.
    Но,как я заметил,сжирает постепенно память(примерно 400мб с заполненного диска в 100Гб,около 220000 файлов),заполняя не выгруженный пул памяти.
    Я предполагаю,проблема в инициализации переменных в начале кода и в самой рекурсии.
    Если найденный файл является директорией(папкой),функция вызывает сама себя,передавая в качестве аргумента найденную папку и снова,и снова.
    Если файл не является директорией,строка передаётся в другую функцию.
    Таким образом,вызывая саму себя(дубликат),функция создаются новые переменные в которые пишутся строки,а старые не выгружаются,так как функция не завершилась.И так с каждой папкой.
    Подскажите,пожалуйста,как можно избавится от этой проблемы.
    ExpandedWrap disabled
      DWORD WINAPI SearchFiles(LPVOID lpName)
      {
          LPTSTR lpszFileName = (LPTSTR)GlobalAlloc(GMEM_FIXED, 1024);//lpszFileName,path переменные,
          LPTSTR path         = (LPTSTR)GlobalAlloc(GMEM_FIXED, 1024);    //которые инициализируются
          ZeroMemory(lpszFileName, 1024);                                              //и не выгружаются
          ZeroMemory(path, 1024);
       
          lstrcpy(lpszFileName, lpName);
          lstrcpy(path, lpszFileName);
          lstrcat(path, "*.*");
       
          HANDLE hand;
          WIN32_FIND_DATA data_file;
          hand = FindFirstFile(path, &data_file);
       
          if (hand != INVALID_HANDLE_VALUE)
          {
              do
              {
                  if (!strncmp(data_file.cFileName, ".", 1) || !strncmp(data_file.cFileName, "..", 2))
                  {
                      continue;
                  }
                  if (data_file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                  {
                      lstrcpy(path, lpszFileName);
                      lstrcat(path, data_file.cFileName);
                      lstrcat(path, "\\");
       
                      if (!lstrcmpi(path, WinPathD) == 0) //WinPathD - папка windows
                      {
       
                          SearchFiles((LPVOID)path); //тут функция вызывает сама семя
                      }
                  }
                  else
                  {
       
                          lstrcpy(file, lpszFileName);    // file глобальная переменная типа LPTSTR
                          lstrcat(file, data_file.cFileName);
       
                          Thread(file);
                  }
              } while (FindNextFile(hand, &data_file) != 0);
          }
          FindClose(hand);
       
          GlobalFree(lpszFileName);
          GlobalFree(path);
       
          return 0;
      }
      Цитата Sherman @
      Но,как я заметил,сжирает постепенно память(примерно 400мб с заполненного диска в 100Гб,около 220000 файлов),заполняя не выгруженный пул памяти.

      220 тыс файлов?
      Я правильно понимаю, что ты так и создаёшь отдельный поток на каждый файл? Если да, то они, потоки, и жрут память.
        Цитата Sherman @
        Я предполагаю,проблема в инициализации переменных в начале кода и в самой рекурсии.

        Если не нравится рекурсивный поиск, сделай не рекурсивный.
        Сравни результаты и выбери то, что больше понравилось.
          Цитата Олег М @
          Я правильно понимаю, что ты так и создаёшь отдельный поток на каждый файл?

          Не на каждый,кол-во потоков ограниченно 10,когда их становится 10,функция ждёт их завершения и снова создаёт.

          Добавлено
          Цитата ЫукпШ @
          Если не нравится рекурсивный поиск, сделай не рекурсивный.

          К сожалению,я не знаю,как это сделать.Всё,что находил в интернете,связанно с рекурсией.
          Если только искать в одной конкретной папке,то без нее.
            Цитата Sherman @
            Не на каждый,кол-во потоков ограниченно 10,когда их становится 10,функция ждёт их завершения и снова создаёт.

            CloseHandle() делаешь для них?
            Покажт полный код
              Цитата Олег М @
              CloseHandle() делаешь для них?

              ExpandedWrap disabled
                                    if( memory(1) < 85 && // memory(1) %загрузки памяти
                                               ff < THREADS ) // THREADS = 10
                                    {
                                        hThreadF[ff] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)rFile, 0, NULL);
                                    }
                                    else
                                    {
                                        printf("\r\n*************************************************************\r\n\r\n");
                 
                                        for(int i = 0; i < ff; i++)
                                            WaitForSingleObject(hThreadF[i], INFINITE);
                 
                                        for(int i = 0; i < ff; i++)
                                            CloseHandle(hThreadF[i]);
                 
                                        ff = 0;
                                    
                                        hThreadF[ff] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)rFile, 0, NULL);
                                    }
                                    ff++;

              Цитата Олег М @
              Покажт полный код

              хорошо,сейчас всё переписываю,как напишу,скину.
                Цитата Олег М @

                Раз уж речь зашла о потоках,не могли бы вы мне подсказать,если я создаю поток
                ExpandedWrap disabled
                  hThreadF[ff] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)rFile, 0, NULL);

                Он может создаться не сразу,точнее говоря,нужно время на его создание,при этом,переменная (LPVOID)rFile,которую я передаю в поток,после этой строчки,меняется.
                Эта переменная не является глобальной.
                Когда поток будет создан,функция Thread получит уже изменённую переменную или то,что именно этому потоку и передавалось?
                  Цитата Sherman @
                  Когда поток будет создан,функция Thread получит уже изменённую переменную или то,что именно этому потоку и передавалось?

                  Поток создаётся сразу, исполняется позже. Значение будет передано то, которое на момент вызова CreateThread. И если ты не удаляешь этот ресурс в вызывающем потоке, то всё будет нормально.
                    Цитата Олег М @
                    И если ты не удаляешь этот ресурс в вызывающем потоке, то всё будет нормально.

                    fFile пересодаётся,не означает ли это,что прежний fFile будет удалён?
                    ExpandedWrap disabled
                                  else
                                  {
                       
                                          LPTSTR fFile = (LPTSTR)GlobalAlloc(GMEM_FIXED, lstrlen(lpszFileName) + lstrlen(data_file.cFileName) + 1);
                                          assert(fFile);
                                          lstrcpy(fFile, lpszFileName);
                                          lstrcat(fFile, data_file.cFileName);
                       
                                          if( memory(1) < 85 &&
                                                     ff < THREADS )
                                          {
                                              hThreadF[ff] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)fFile, 0, NULL);
                                          }
                                          else
                                          {
                                              printf("\r\n*********************************************************************\r\n\r\n");
                       
                                              for(int i = 0; i < ff; i++)
                                                  WaitForSingleObject(hThreadF[i], INFINITE);
                       
                                              for(int i = 0; i < ff; i++)
                                                  CloseHandle(hThreadF[i]);
                       
                                              ff = 0;
                                          
                                              hThreadF[ff] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)fFile, 0, NULL);
                                          }
                                          ff++;
                                  }
                      Цитата Sherman @
                      fFile пересодаётся,не означает ли это,что прежний fFile будет удалён?

                      Нет, не будет. Здесь всё более-менее правильно

                      Добавлено
                      Надеюсь, в потоке ты делаешь для него GlobalFree?
                        Цитата Олег М @

                        Спасибо.
                        Как можно освободить память,выделяемую этой переменной?
                        ExpandedWrap disabled
                          LPTSTR fFile = (LPTSTR)GlobalAlloc(GMEM_FIXED, lstrlen(lpszFileName) + lstrlen(data_file.cFileName) + 1);

                        Я пытаюсь вызвать GlobalFree для LPVOID в функции потока Правильный ли это подход?
                        ExpandedWrap disabled
                          DWORD WINAPI Thread(LPVOID gfile) {
                              // UNREFERENCED_PARAMETER(gfile);
                           
                              LPTSTR nfile = (LPTSTR)GlobalAlloc(GMEM_FIXED, SizeBuf);
                              ZeroMemory(nfile, SizeBuf);
                              lstrcpy(nfile, (TCHAR*)gfile);
                              GlobalFree(gfile);
                              over++;
                           
                              printf("%d %s\r\n", over, nfile);
                              GlobalFree(nfile);
                              Sleep(8000);
                           
                              return 0;
                          }
                        Сообщение отредактировано: Sherman -
                          ExpandedWrap disabled
                            DWORD WINAPI Thread(LPVOID gfile) {
                                // UNREFERENCED_PARAMETER(gfile);
                             
                                over++;
                             
                                printf("%d %s\r\n", over, (LPCSTR)gfile);
                                GlobalFree(gfile);
                                Sleep(8000);
                             
                                return 0;
                            }
                            Цитата Sherman @
                            К сожалению,я не знаю,как это сделать.Всё,что находил в интернете,связанно с рекурсией.
                            Если только искать в одной конкретной папке,то без нее.

                            Алгоритм простой.
                            Заготовим 2 списка строк - один для директорий, другой для файлов.
                            Занесём начальную директорию (полный путь) в список директорий.
                            Дальше начинается основной алгоритм.
                            ---
                            1. Проверяем, наличие строк в списке директорий.
                            2. Если нет - работа окончена, в списке файлов результат поиска.
                            3. Если есть - извлекаем 1-ю по счёту строку из списка, будем искать в этой директории
                            - отдельно файлы, добавляя результат в список файлов (полные пути).
                            - отдельно директории, добавляя результат в список директорий (полные пути).
                            4. закончился поиск в текущей директории - переход к пункту 1.
                            Это всё.
                            ---
                            Результатом работы алгоритма является список строк имен файлов (полные пути).
                              Спасибо,большое.Я уже так сделал,вроде работает.
                              Попробую,как память себя ведёт.
                                Я проверил твою функцию на своём движке в подобной утилите (поиск совпадающих под контексту файлов). Она показала те же затраты, что и мой движок. И они гораздо скромнее: 168Мб на без малого миллионе файлов. Так что если где и утечка, то явно не в SearchFiles()
                                  Цитата Qraizer @
                                  Так что если где и утечка, то явно не в SearchFiles()

                                  Согласен.fFile была объявлена глобально.Думаю,проблема была в этой переменной.
                                  Перенёс её в функцию и передаю как аргумент,там же выделяю память.
                                  Перепишу и протестирую.
                                  Спасибо,что проверили.

                                  Добавлено
                                  Цитата ЫукпШ @

                                  Благодарю.Интересный подход.Обязательно попробую.
                                    Цитата Sherman @
                                    Интересный подход

                                    Интересный подход для FAT, и в тоже время - неинтересный для NTFS.
                                    Все почему-то помнят только про файлы и каталоги, но напрочь забывают по хард-линки.
                                    А ведь так можно и улететь в бесконечный скан.
                                      Только не хард-линки, а соединения, да и то только для каталогов. Хотя для файлов тоже имеет смысл сканить, чтоб не обрабатывать дубликаты, но к ошибкам это-таки не приведёт.

                                      P.S. Если уж заводить разговор за стратегически правильный код, то там много что учитывать надо. Нужно отсекать как минимум FILE_ATTRIBUTE_TEMPORARY и FILE_ATTRIBUTE_OFFLINE. Нужно пытаться зайти в очередной каталог и проверять успех, а то вдруг прав нет туда заглядывать, иначе тоже легко можно свалиться в бесконечный скан одного и того же каталога. И если речь о каком-то аналоге бэкапа, было бы неплохо хотя бы пробовать не обновлять время доступа к очередному файлу, чтоб не ломать статистику по частоте использования.
                                        Цитата JoeUser @
                                        Все почему-то помнят только про файлы и каталоги, но напрочь забывают по хард-линки.

                                        Что-то вообще сложное... .Попробую изучить эту тему.Спасибо.

                                        Добавлено
                                        Есть вопрос по кол-ву потоков.
                                        Пишу программку,которая будет искать все файлы на ПК,проверяя расширение файла.
                                        Если расширение файла совпадает с тем,что я укажу,mp4 например,создаёт поток передавая функции потока строку,содержащую полный путь к файлу.
                                        Функция потока,в свою очередь,копирует найденные файлы на внешний жёсткий,который я тоже укажу.
                                        Для этого я использую функции WINAPI(CreateFile,CreateFileMapping,MapViewOfFile).
                                        Какое кол=во потоков можно использовать,для этой задачи?
                                        Пока я просто ищу файлы,передаю строки в потоки и там вывожу их в консоль.
                                        Так же вывожу целое число,которое соответствует кол-ву переданных строк в функцию потока.
                                        Но я заметил,что число файлов показывает разное,при одинаковых условиях.
                                        Чем больше потоков,тем больше разница.
                                        Пробовал от 2 до 5000 потоков.(в качестве эксперимента)
                                        На 500 потоков разнице +-10,на 5000 около 100000 строк.
                                          Цитата Qraizer @
                                          P.S. Если уж заводить разговор за стратегически правильный код, то там много что учитывать надо. Нужно отсекать как минимум FILE_ATTRIBUTE_TEMPORARY и FILE_ATTRIBUTE_OFFLINE.

                                          я делал так:
                                          Для файлов : FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_OFFLINE
                                          Для директорий : FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_REPARSE_POINT
                                          И конечно, проверка на ошибку "ERROR_ACCESS_DENIED".
                                          Детали я точно не помню. Но ничего страшного с запретом доступа нет.
                                          Перечислить такую директорию (убедиться в её наличии) можно,
                                          а искать файлы внутри нельзя. Произойдёт ошибка и цикл завершиться, ничего
                                          страшного. Следить за этой ошибкой полезно исключительно в информационном смысле,
                                          для выдачи сообщения, что "зайти туда было запрещено".
                                          Сообщение отредактировано: ЫукпШ -
                                            Цитата ЫукпШ @
                                            И конечно, проверка на ошибку "ERROR_ACCESS_DENIED".

                                            Не подскажете,как сделать эту проверку?
                                              Цитата Sherman @
                                              Какое кол=во потоков можно использовать,для этой задачи?


                                              Цитата Sherman @
                                              Функция потока,в свою очередь,копирует найденные файлы на внешний жёсткий,который я тоже укажу.
                                              Для этого я использую функции WINAPI(CreateFile,CreateFileMapping,MapViewOfFile).
                                              Какое кол=во потоков можно использовать,для этой задачи?

                                              Я ж тебе вроде писал, что достаточно трёх потоков. С тех пор ничего не изменилось.
                                              Не работает функция в потоке _beginthreadex (сообщение #3798301)
                                                Цитата Qraizer @
                                                Только не хард-линки, а соединения, да и то только для каталогов.

                                                Ну я образно. Хотя ты прав недо-хардлинки :)

                                                Цитата Sherman @
                                                Что-то вообще сложное... .Попробую изучить эту тему.Спасибо.

                                                Так это еще не все, не расслабляйся! :lol: Надо искать файлы, которых "в явном виде нет, а они есть". Я про NTFS-потоки, а-ля:
                                                ExpandedWrap disabled
                                                  echo file-1>file-1.txt
                                                  echo secret-1>file-1.txt:secret-1.txt

                                                Файл secret-1.txt в листинге dir не виден. Но он есть, и он - в потоке файла file-1.txt, и можно убедиться:
                                                ExpandedWrap disabled
                                                  notepad file-1.txt
                                                  notepad file-1.txt:secret-1.txt
                                                  Цитата Олег М @
                                                  Я ж тебе вроде писал, что достаточно трёх потоков. С тех пор ничего не изменилось.

                                                  Да,я помню,но с тем способом вообще беда у меня.
                                                  Я даже нигде не встречах подобие того,что вы описали.

                                                  Добавлено
                                                  Цитата JoeUser @

                                                  :blink:
                                                  Сообщение отредактировано: Sherman -
                                                    Цитата Sherman @
                                                    Цитата ЫукпШ @
                                                    И конечно, проверка на ошибку "ERROR_ACCESS_DENIED".

                                                    Не подскажете,как сделать эту проверку?

                                                    ExpandedWrap disabled
                                                       BOOL RetC=FALSE;
                                                       // ...
                                                                 hFind = ::FindFirstFile(pTempName, &FindFileData);
                                                                 if(hFind == INVALID_HANDLE_VALUE) {RetC = FALSE;}
                                                                 else                              {RetC = TRUE; }
                                                       //...
                                                                 RetC = ::FindNextFile(...);
                                                       
                                                       if(RetC == FALSE)
                                                       {
                                                         DWORD LE = ::GetLastError();
                                                       
                                                      // возможные результаты окончания
                                                         if(LE == ERROR_NO_MORE_FILES)  {...}  // ERROR_NO_MORE_FILES = 18, больше файлов не осталось
                                                         if(LE == ERROR_FILE_NOT_FOUND) {...}  // ERROR_FILE_NOT_FOUND = 2, файл не найден
                                                         if(LE == ERROR_PATH_NOT_FOUND) {...}  // ERROR_PATH_NOT_FOUND = 3, path не найден
                                                       
                                                      // доступ запрещён
                                                         if(LE == ERROR_ACCESS_DENIED) {...}
                                                       
                                                      // другое - совсем плохо
                                                       }
                                                    Сообщение отредактировано: ЫукпШ -
                                                      Цитата ЫукпШ @

                                                      Большое, спасибо!
                                                        Цитата Sherman @
                                                        Да,я помню,но с тем способом вообще беда у меня.
                                                        Я даже нигде не встречах подобие того,что вы описали.

                                                        А что встречал - как на каждый чих зафигачить поток, авось система сама разберётся?

                                                        Вообще - не надо решать все проблемы одновременно. Все эти хардлинки с атрибутами это вторичная проблема, не факт, что с ней столкнёшься.
                                                        Основной алгоритм здесь - асинхронный поиск и копирование, у тебя он не решён. Лучше сосредоточиться на нём, а когда заработает как часы, тогда уже можно заняться и деталями.
                                                          Цитата Олег М @
                                                          Все эти хардлинки с атрибутами это вторичная проблема, не факт, что с ней столкнёшься.

                                                          Не правда твоя! :)

                                                          Берем системный диск любой современной версии винды и видим сразу же в корне соединение "Users" -> "Documents and Settings":

                                                          user posted image
                                                            Цитата JoeUser @
                                                            Не правда твоя!

                                                            Необязательно тестировать на Document and Settings.
                                                              Точнее - лучше не сканить систем диск с корня, иначе сбудутся пророчества тяжёлых времён :-)
                                                                Цитата Олег М @
                                                                Лучше сосредоточиться на нём, а когда заработает как часы, тогда уже можно заняться и деталями.

                                                                Полностью согласен.На данный момент я и копирование не делаю.Занимаюсь только настройкой поиска и потоков.

                                                                Добавлено
                                                                Цитата Олег М @
                                                                А что встречал - как на каждый чих зафигачить поток, авось система сама разберётся?

                                                                Нет,не встречал.Но встречал программку,которая делала что-то подобное и делала это очень быстро,и потоков было с лихвой.
                                                                Вот только кода этой программки я не видел,да и её самой у меня уже нет.
                                                                Случайно наткнулся,не думал на тот момент,что сам заинтересуюсь.
                                                                Всё,что я пока делал,работает очень медленно.
                                                                Всё,что я знаю о той проге, это то,что она работает с большим количеством потоков и с WINAPI.
                                                                Пробовал выполнять копирование при помощи Си (FILE*) и WINAPI(CreateFile),заметил,что WINAPI работает намного быстрее.
                                                                Думаю я на верном пути.

                                                                Добавлено
                                                                Цитата JoeUser @
                                                                Берем системный диск любой современной версии винды и видим сразу же в корне соединение "User" -> "Documents and Settings":

                                                                Если я запускаю программу не от имени админа,она эти папки даже не видит,а есть и такие,для которых и вовсе прав админа не достаточно,
                                                                нужно что-то вроде привилегий SE_BACKUP_NAME
                                                                Но в моём случае,это не не нужно и даже вредно.
                                                                  Цитата Sherman @
                                                                  и потоков было с лихвой

                                                                  Олег М в своих предыдущих сообщения был во многом прав по поводу потоков. А мое резюме - ты люто и бешено зациклен на многопоточности. Народная мудрость гласит "все хорошо в меру". И тут это как ни кстати - актуально!

                                                                  Пример. Берем восми-ядерный проц. И запускаем сборку Цэ++ проекта. Сколько потоков выделить на сборку?
                                                                  Скрытый текст
                                                                  Тут сикретик. И мой ответ тамошний - в топах. Народ кагбэ одобяет.

                                                                  А вот теперь подумай, у тебя простой скан диска. Сколько операций твой дисковый массив сможет сделать одновременно? Универсального ответа нет. Если это честный хардварный рэйд - он закэширует твои вызовы хорошо, но все равно выполнит их последовательно или псевдо-параллельно. Если это мамковый fake-рэйд, сделает тоже самое, но плюс к тому загрузит камень, к гадалке не ходи! Единственный вменяемый вариант - когда идет одновременный скан n-независимых дисков, сидящих на разных интерфейсах.

                                                                  Резюме

                                                                  1) Если какого-то трудного пересчета нет - не делай потоков больше, чем количество отдельных физических носителей
                                                                  2) Не верю что 2-х поточная прога на 2-х винтовом рэйде сильно победит однопоточную (если вообще сможет) и не уступит 3-х поточной

                                                                  ЗЫ: Если захочешь узнать три Закона Будды - пиши в личку.

                                                                  Добавлено
                                                                  Цитата Sherman @
                                                                  Но в моём случае,это не не нужно и даже вредно.

                                                                  Тебе виднее для твоего случая. Без вопросов :lol:
                                                                    Цитата JoeUser @
                                                                    Цитата Олег М @
                                                                    Все эти хардлинки с атрибутами это вторичная проблема, не факт, что с ней столкнёшься.

                                                                    Не правда твоя! :)

                                                                    Берем системный диск любой современной версии винды и видим сразу же в корне соединение "User" -> "Documents and Settings":

                                                                    Не совсем понятно, о чём дискуссия..
                                                                    У этой директории просто установлены атрибуты:
                                                                    FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_REPARSE_POINT
                                                                    (и конечно FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
                                                                    Если захочется специально проигнорировать объект с такими атрибутами
                                                                    это можно сделать. И в результате игнорировать такую директорию для дальнейших действий.
                                                                    Если поиск не фильтровать по атрибутам, директория будет найдена.
                                                                    Сообщение отредактировано: ЫукпШ -
                                                                      ЫукпШ, да я к тому - что файловый носитель уже давно ушел от древовидной структуры.
                                                                      И только упоротый гик пытается делать обход "дерева", не взирая на все увещевания.
                                                                      Я кончил.
                                                                        Цитата ЫукпШ @
                                                                        Если захочется специально проигнорировать объект с такими атрибутами ...
                                                                        В отношении FILE_ATTRIBUTE_REPARSE_POINT мнение может быть двояким. С одной стороны, они являются ссылками на другие объекты, которые либо находятся вне рассматриваемой области тома, а то и вообще другого тома, либо и без учёта этой ссылки тоже будут обработаны. С другой же стороны, не зря же эта ссылка тут расположена, значит кому-то было нужно, чтобы та, другая, область (другого) тома вроде бы считалась как будто бы находящаяся тут. Так что этот аспект не абсолютен и вполне себе обсуждаем, и наличие этого атрибута у объекта целиком и полностью зависит от пользователя. Даже не автора программы. JoeUser же говорил о другом его аспекте: этот атрибут может иметь объект, ссылающийся на одного из своих родителей. И это уже куда серьёзней, так как его игнор ведёт к бесконечной петле. Попробуй его не игнорировать и при этом не допустить циклов. Это не так-то просто запрограммировать.
                                                                        С другими атрибутами другая петрушка. FILE_ATTRIBUTE_TEMPORARY выставляется приложениями для объектов, которые являются порождениями реализаций их внутренних алгоритмов. Такие объекты используются ими временно, для внутренних нужд и не содержат полезной для пользователя информации. Игнорировать такие объекты сам бог велел, ибо зачем обрабатывать мусор?
                                                                        FILE_ATTRIBUTE_OFFLINE говорит о том, что объект в данный момент недоступен, поэтому его обработка непосредственно сейчас может оказаться невозможной или потребовать от пользователя телодвижений, т.е. неких ручных операций, для обеспечения доступа к нему. Вряд ли пользователя это обрадует, тем более, что он всё равно, зная, что запускает приложения по обработке данных, должен был бы заранее озаботиться предоставлением доступа ко всем таким объектам, и тогда этот атрибут был бы с них уже снят. Да, он может об этом не подумать или просто забыть о парочке таких, однако останов программы, запущенной на ночь для длительной обработки в нерабочее время, в паузу поутру может обернуться неслабыми матюгами. Из-за одного объекта не были обработаны куча других, вполне нормальных. Поэтому будет хорошей практикой все такие объекты обходить, чтоб не тормозить себе работу, однако включить их отчёт о проделанной работе как о непроделанной.
                                                                          Цитата Sherman @
                                                                          Всё,что я пока делал,работает очень медленно.
                                                                          Всё,что я знаю о той проге, это то,что она работает с большим количеством потоков и с WINAPI.

                                                                          Думаю, первое вытекает из второго.
                                                                          Скорее всего, она использует асинхронный ввод-вывод, виндовский, а тот, в свою очередь - пул потоков.
                                                                            Цитата Олег М @
                                                                            Скорее всего, она использует асинхронный ввод-вывод, виндовский, а тот, в свою очередь - пул потоков.

                                                                            OVERLAPPED это то что мне нужно?
                                                                            Вчера только наткнулся на эту "фишку".
                                                                            Переодически веду всякие заметки по программированию в блокноте.Нашёл и о этой программке заметку.
                                                                            Она использовала CreateFileW,CreateFileA,CreateFileMappingA,MapViewOfFile,UnmapViewOfFile,SetFilePointerEx,WriteFile,GlobalAlloc,GlobalFree,RtlZeroMemory,CreateThread,
                                                                            По крайней мере,это было в листинге дис-ассамблера.
                                                                            Здесь не случайно нет ReadFile.
                                                                            По всей видимости,она проецировала файл(карту) в виртуальной памяти,читала карту блоками и писала в другой.
                                                                            Если это делать,как вы писали,разделить эти процедуры по разным потокам,получается,нужно в одном потоке искать файлы,во-втором проецировать
                                                                            файл и передавать в третий хедл CreateFileMappingA,в котором,в свою очередь,читать карту(MapViewOfFile) и писать в файл?
                                                                              Цитата Sherman @
                                                                              OVERLAPPED это то что мне нужно?

                                                                              Нет. Сначала тебе нужно сделать то что я тебе рекомендовал, это самое простое, с чего надо начинать. Проецирование и т.п. - это следующий шаг, не стоит перескакивать.
                                                                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                              0 пользователей:


                                                                              Рейтинг@Mail.ru
                                                                              [ Script execution time: 0,1090 ]   [ 17 queries used ]   [ Generated: 16.04.24, 22:55 GMT ]