Как правильно организовать работу с файлом?

Тема в разделе "WASM.WIN32", создана пользователем Oleg_SK, 8 фев 2005.

  1. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    Мне нужно написать процедуру (используя ассемблер + Win32 API), которая бы посчитала контрольные значения для указанного файла тремя способами. Размер файла не ограничивается, поэтому в общем случае можно считать, что его не удастся загрузить в память полностью. Во время своей работы процедура должна показывать объем выполненной работы в дочернем контроле progress bar. В общем, задачка довольно простая, но хотелось бы чтобы эта процедура была оптимизирована по скорости работы, и в то же время имела бы не большой размер кода (но оптимизация по скорости работы более важна). Также хотелось бы, чтобы она в полном объеме использовала ресурсы памяти установленной на компе, т.е. чтобы она при прочих равных работала бы быстрее на той машине, где установлено больше памяти. Процедура ориентирована для работы под Windows9x+ и Windows 2000+. Вот такая задачка. Процедуры для подсчета контрольных значений у меня есть. Осталось только разобраться, как в данном случае лучше всего организовать работу с файлом. Вообще-то я и сам могу это сделать, но у меня ещё мало опыта, поэтому мое решение, скорее всего, не будет оптимальным. Поэтому вопрос к вам: как в данном случае оптимально организовать работу с файлом?
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    А в чем проблема-то ?

    Как я понимаю, для расчета контрольных значений достаточно один раз прочитать файл блоками от начала до конца. Поэтому проблем с памятью вроде как и нет. Зависимости от размера установленной физической памяти реально тоже нет. В данном случае основной тормоз - это ИМХО скорость обмена с диском, особенно если файл фрагментирован.



    Так что ИМХО читай себе блоками по 16, 32 или 64 Кб, считай контрольные значения и не парься. Можно открыть файл с флагом FILE_FLAG_NO_BUFFERING - вроде как чуть быстрее получается. Но при этом адрес и размер буфера д.б. кратен 512 байт. Если использовать Buf=VirtualAlloc(Null,..) - автоматом получишь выравнивание на 64Кб.
     
  3. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    leo



    Да нет, проблемы никакой нет. Просто хотелось бы узнать, как лучше всего это дело организовать. К примеру какой механизм работы с файлами больше подходит в данной ситуации: обычный (ReadFile, WriteFile), обычный с перекрытием (OVERLAPPED) или MMF? Также хотелось бы узнать, как можно подобрать оптимальный размер буфера (или буферов)?





    А что блоки то такие маленькие, или это не влияет на скорость? IMHO, если использовать механизм работы с файлами с перекрытием и сделать буфера достаточного размера, то можно подсчитывать контрольное значение для одного буфера, в то время как другой за это время будет заполнен следующим блоком файла.





    Спасибо за подсказку, я обязательно учту её.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Oleg_SK



    OVERLAPPED не поддерживается в 9x. Хоть Win98 и маст дай, но еще далеко не дед.

    <font color="gray]<font size=2>Windows Me/98/95: For asynchronous read operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by socket or accept. You cannot perform asynchronous read operations on mailslots, named pipes, or disk files.

    Windows Me/98/95: For operations on files, disks, pipes, or mailslots, this parameter must be NULL; a pointer to an OVERLAPPED structure causes the call to fail. (GetLastError = ERROR_INVALID_PARAMETER = 87)</font><!--size--></font><!--color-->



    MMF в данном случае работает гораздо дольше. Попробовал для примера два файлика 70 и ~100Мб на разных компах, получилось в ~1.5 и ~2 раза дольше, чем обычное блочное чтение. Эти же примерчики показывают, что увеличение размера буфера свыше 32-64К практически ничего не дает. Кстати, выбор "маленьких" блоков хорош с точки зрения кэширования данных при расчете несколько контрольных значений (хотя повторная загрузка данных из памяти в кэш существенно быстрее чем чтение с диска, но все таки).



    Попробуй сам с разными размерами буфера. Для экспериментов кстати нужно обязательно использовать флаг FILE_FLAG_NO_BUFFERING, иначе после первого же прохода файл попадет в файловый кэш и результаты последующих чтений будут занижены.



    PS: Что-то народ безмолвствует на эту тему ...
     
  5. Oleg_SK

    Oleg_SK Guest

    Публикаций:
    0
    leo

    Это именно то, что я хотел услышать! Спасибо за помощь!