Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 5.00
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Максимально эфективное бинарное чтение из файла под Windows - C++

14.12.2012, 02:50. Просмотров 2408. Ответов 40
Метки нет (Все метки)

Задача: максимально эфективно (быстро) читать данные из файла. Каким это будет происходить образом - в виде си функции, с++ или винапи функции не имеет значения, имеет значение лишь результат.
Как мне известно размер странички в Windows = 4Кб так что быстрее всего по идее чтение должно происходить если читать по 4 кб, но как лучше всего это сделать?

Вообще в итоге я буду использоать 64битные значения после того как считаю кусок файла. Вот мой маленький набросок, который првда закончился фиаско потому что стандартная fread, как оказалось, имеет буфер под чтение меньше 4 кб так что нужно что-то другое быстрое
C++
1
2
3
4
5
6
7
    FILE* readFrom = fopen("input.bin","rb"); _ASSERT(readFrom);
    uint64_t bufferRead[64];//мой буффер на 4 кб
    size_t countBlocks;//считано блоков
 
        // вернёт 0 потому что fread не может считать 4096 байтиков
    countBlocks = fread(bufferRead,1,4096,readFrom);
    fclose(readFrom);
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.12.2012, 02:50     Максимально эфективное бинарное чтение из файла под Windows
Посмотрите здесь:
Бинарное чтение файла C++
Бинарное чтение файла C++
Бинарное чтение из файла с пoмощью функции fread() C++
C++ Чтение файла под WATCOM
Найти сумму максимально отрицательного и максимально положительного элемента массива C++
Бинарное считывание с файла и бинарный вывод. C++
C++ Считать из файла целочисленный массив C[N] и сформировать из него максимально возможную матрицу А [n x n]
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
17.12.2012, 01:24     Максимально эфективное бинарное чтение из файла под Windows #31
Gepar, если тебе нужна скорость, то почему ты не задействуешь файлы проецируемые в память
грубо говоря создается копия файла в озу
ты работаешь с этой копией (скорость обращения к памяти намного больше чем к винту) точно так же как с файлом
потом при закрытии он скидывается на диск

Добавлено через 3 минуты
вот вроде неплохая статейка
http://www.developing.ru/com/memory_..._files_01.html
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 01:47  [ТС]     Максимально эфективное бинарное чтение из файла под Windows #32
ValeryS, я почитаю сейчас, но почему WriteFile может писать по 0 байт? Не, ну хотябы мусор там какой-то писала или ещё чего, а так файл получается в 0 байт независимо от того сколько я пытался писать ею, почему же?
*Вообще я смотрю 98% времени таки тратиться на шифрование, даже если читать по 4 кб максимум так что я думаю на чтении файла не стоит совсем сильно заострять внимание, чтение через винапи функции без буферизации должно быть достаточно, но нужно исправить эту багу с WriteFile ...
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
17.12.2012, 02:22     Максимально эфективное бинарное чтение из файла под Windows #33
Цитата Сообщение от Gepar Посмотреть сообщение
но почему WriteFile может писать по 0 байт?
не может
это значит какая то ошибка при записи вызывай GetLastError.
http://vsokovikov.narod.ru/New_MSDN_..._writefile.htm
особенно посмотри раздел Замечания

Добавлено через 4 минуты
я кстати в коде не нашел проверки outputData
файл ведь может не открыться
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 03:00  [ТС]     Максимально эфективное бинарное чтение из файла под Windows #34
Цитата Сообщение от ValeryS Посмотреть сообщение
это значит какая то ошибка при записи вызывай GetLastError.
Отдаёт код 57 после записи файла (до записи 0, те ошибка была при записи). Как определить что произошло, я уже позабывал эти винапишные штучки, там вроде что-то было для этого.

Добавлено через 44 секунды
Цитата Сообщение от ValeryS Посмотреть сообщение
я кстати в коде не нашел проверки outputData
файл ведь может не открыться
Оно бы вываливалось тогда при записи, файл открывается, я в отладчике просто смотрел что хендлер получен корректный.
activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
17.12.2012, 03:09     Максимально эфективное бинарное чтение из файла под Windows #35
Цитата Сообщение от Gepar Посмотреть сообщение
Как определить что произошло
исключения же
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
17.12.2012, 03:14     Максимально эфективное бинарное чтение из файла под Windows #36
Цитата Сообщение от Gepar Посмотреть сообщение
Как определить что произошло,
Примерно так
C++
1
2
 if(!(WriteFile(outputData,&pBuf[readed/8],(DWORD)8,&writed,0))
      GetLastError();
потом в меню (в студии) сервис - поиск ошибки набиваешь номер и читаешь расшифровку

Цитата Сообщение от Gepar Посмотреть сообщение
Отдаёт код 57 после записи файла
аппаратная неисправность сетевой платы
а вот 0х57 уже ближе
Параметр задан неверно.
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
17.12.2012, 08:20     Максимально эфективное бинарное чтение из файла под Windows #37
При записи файла, открытого с флагом FILE_FLAG_NO_BUFFERING нужно писать также как и читать - размером кратным размеру сектора (512 байт). Буфер для записи нужно выровнять (выделить память VirtualAlloc). В конце (если размер выходного файла не кратен 512) нужно вызвать SetEndOfFile. Имеет смысл формировать буфер как можно больший - т.к. чем меньше обращений к диску, тем лучше. Минимум, если размер файла позвоялет - 64Кб.
При чтении файлов с флагом FILE_FLAG_NO_BUFFERING и чтении файла через проекцию (FileMapping) - скорость первого примерно на 15%-30% выше.
Писать возможно и правда лучше и удобней в проецируемый файл.
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 12:27  [ТС]     Максимально эфективное бинарное чтение из файла под Windows #38
Цитата Сообщение от WhiteP Посмотреть сообщение
При записи файла, открытого с флагом FILE_FLAG_NO_BUFFERING нужно писать также как и читать - размером кратным размеру сектора (512 байт).
Так я же так и делаю - я записываю тот буфер полностью, те 64 кб, но после той записи в DWORD writed по прежнему 0, но почему ? Или оно не скинеться на диск пока я не вызову SetEndOfFile? Но тогда где оно держит по 50 мб которые я пытался шифровать, не в оп же, я же смотрел что моё приложение так много оп не жрёт. Можешь ещё раз посмотреть на мой код, может заметишь что не так. Вроде же всё просто: считал в буфер 64 кб, записал их в файл, если считал меньше 64 кб - поредактировал последний блок и снова записал в файл. По крайней мере первые же записи что по полных 64 кб должны писаться, но я отладчиком гоняю и writed постоянно = 0 и не меняется. Столько проблем с десом этим
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
17.12.2012, 14:31     Максимально эфективное бинарное чтение из файла под Windows #39
Цитата Сообщение от Gepar Посмотреть сообщение
я записываю тот буфер полностью, те 64 кб,
чей то я не увидел
Цитата Сообщение от Gepar Посмотреть сообщение
WriteFile(outputData,&lastBlock,(DWORD)8,&writed,0);
8 байт
64 кб это все таки 65536
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
17.12.2012, 14:45     Максимально эфективное бинарное чтение из файла под Windows #40
C++
1
_ASSERT(WriteFile(outputData,pBuf,readed-(readed%8),&writed,0)==0);//отрабатывает без ошибок, но нифига не пишеет!
Если размер файла меньше 512 байт, например, то писать и не будет. Последний блок также может не записаться и в других случаях, т.к. не все то, что кратно 8 кратно 512.
Тут надо
C
1
2
#define ALIGN_UP(x, align) ((x)+((align)-1))&(~((align)-1))
WriteFile(outputData,pBuf,ALIGN_UP(readed, 512),&writed,0)
Запустил в студии вот такой код. Файл скопировался без проблем.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    
    HANDLE hFile = CreateFileW(L"c:\\input.bin", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, 0);
 
    HANDLE hOutFile = CreateFileW(L"d:\\out.bin", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, 0);
...
while(isOk = ReadFile(hFile, pBuf, BUFSIZE, &readed, 0))
    {
        //std::cout<<"Step "<<step++<<". Readed bytes: "<<readed<<std::endl;
        fSize+=readed;
 
        //WriteFile(hOutFile, pBuf, (ALIGN_UP(readed, 512)),&written, NULL);
        std::cout << written <<"bytes writed."<<std::endl;
 
        if(readed < BUFSIZE)
            break;
    }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.12.2012, 22:40     Максимально эфективное бинарное чтение из файла под Windows
Еще ссылки по теме:
Соединение двух программ в одну (бинарное сложение и бинарное сравнение) C++
C++ Чтение из файла
Чтение из файла C++
Чтение из файла C++
Чтение из файла C++ C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 22:40  [ТС]     Максимально эфективное бинарное чтение из файла под Windows #41
Цитата Сообщение от WhiteP Посмотреть сообщение
Если размер файла меньше 512 байт, например, то писать и не будет. Последний блок также может не записаться и в других случаях, т.к. не все то, что кратно 8 кратно 512.
Так я понимаю, но полные блоки по 64 кб оно у меня тоже не пишет. Щас буду мучить его.
Yandex
Объявления
17.12.2012, 22:40     Максимально эфективное бинарное чтение из файла под Windows
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru