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

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

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

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

14.12.2012, 02:50. Просмотров 2471. Ответов 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);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.12.2012, 02:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Максимально эфективное бинарное чтение из файла под Windows (C++):

Бинарное чтение файла - C++
FILE *ftm; ftm = _wfopen(fff, L"r+"); //fff - это переменная wchar_t содержащая имя файла! unsigned short buf = { 0 }; ...

Бинарное чтение файла - C++
Что за каракули в конце файла,? Спасибо.

Бинарное чтение из файла с пoмощью функции fread() - C++
Подскажите, пожалуйста, почему feof() может возвращать конец файла далеко до его реального конца? Конец проверяется из обозревателя файлов...

Чтение файла под WATCOM - C++
Всем добрый день! Стоит задача чтения информации из файла. Есть простой код: #include <iostream> #include <fstream> #include...

Бинарное чтение файла - C++ Qt
Всем доброго времени суток. Стоит задача реализовать зашифровать файл RSA ключом в 1024 бит. Но споткнулся с проблемой чтения файла в виде...

Бинарное чтение из файла - C++ Builder БД
Всем доброго времени суток. Столкнулся с проблемой чтения из файла в бинарном режиме. У меня есть исполнительный файл программы для...

40
ValeryS
Модератор
6654 / 5063 / 470
Регистрация: 14.02.2011
Сообщений: 16,934
17.12.2012, 01:24 #31
Gepar, если тебе нужна скорость, то почему ты не задействуешь файлы проецируемые в память
грубо говоря создается копия файла в озу
ты работаешь с этой копией (скорость обращения к памяти намного больше чем к винту) точно так же как с файлом
потом при закрытии он скидывается на диск

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

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

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

Цитата Сообщение от Gepar Посмотреть сообщение
Отдаёт код 57 после записи файла
аппаратная неисправность сетевой платы
а вот 0х57 уже ближе
Параметр задан неверно.
0
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
17.12.2012, 08:20 #37
При записи файла, открытого с флагом FILE_FLAG_NO_BUFFERING нужно писать также как и читать - размером кратным размеру сектора (512 байт). Буфер для записи нужно выровнять (выделить память VirtualAlloc). В конце (если размер выходного файла не кратен 512) нужно вызвать SetEndOfFile. Имеет смысл формировать буфер как можно больший - т.к. чем меньше обращений к диску, тем лучше. Минимум, если размер файла позвоялет - 64Кб.
При чтении файлов с флагом FILE_FLAG_NO_BUFFERING и чтении файла через проекцию (FileMapping) - скорость первого примерно на 15%-30% выше.
Писать возможно и правда лучше и удобней в проецируемый файл.
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 12:27  [ТС] #38
Цитата Сообщение от WhiteP Посмотреть сообщение
При записи файла, открытого с флагом FILE_FLAG_NO_BUFFERING нужно писать также как и читать - размером кратным размеру сектора (512 байт).
Так я же так и делаю - я записываю тот буфер полностью, те 64 кб, но после той записи в DWORD writed по прежнему 0, но почему ? Или оно не скинеться на диск пока я не вызову SetEndOfFile? Но тогда где оно держит по 50 мб которые я пытался шифровать, не в оп же, я же смотрел что моё приложение так много оп не жрёт. Можешь ещё раз посмотреть на мой код, может заметишь что не так. Вроде же всё просто: считал в буфер 64 кб, записал их в файл, если считал меньше 64 кб - поредактировал последний блок и снова записал в файл. По крайней мере первые же записи что по полных 64 кб должны писаться, но я отладчиком гоняю и writed постоянно = 0 и не меняется. Столько проблем с десом этим
0
ValeryS
Модератор
6654 / 5063 / 470
Регистрация: 14.02.2011
Сообщений: 16,934
17.12.2012, 14:31 #39
Цитата Сообщение от Gepar Посмотреть сообщение
я записываю тот буфер полностью, те 64 кб,
чей то я не увидел
Цитата Сообщение от Gepar Посмотреть сообщение
WriteFile(outputData,&lastBlock,(DWORD)8,&writed,0);
8 байт
64 кб это все таки 65536
0
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
17.12.2012, 14:45 #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;
    }
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
17.12.2012, 22:40  [ТС] #41
Цитата Сообщение от WhiteP Посмотреть сообщение
Если размер файла меньше 512 байт, например, то писать и не будет. Последний блок также может не записаться и в других случаях, т.к. не все то, что кратно 8 кратно 512.
Так я понимаю, но полные блоки по 64 кб оно у меня тоже не пишет. Щас буду мучить его.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.12.2012, 22:40
Привет! Вот еще темы с ответами:

Бинарное чтение файла - PHP
&lt;?php @error_reporting ( E_ALL ); @ini_set ( 'display_errors', true ); @ini_set ( 'html_errors', false ); @ini_set (...

Максимально быстрое чтение очень большого файла - C#
Добрый день, задача прочитать очень большой файл (1GB-10GB+). Нужно провести операцию с каждой строкой этого файла. Используя...

Бинарное дерево поиска. Как осуществить запись в файл и чтение из файла - C (СИ)
Добрый день! Если кому не жаль своего времени окажите помощь! Необходимо осуществить запись в файл,просмотр содержимого файла, и создание...

Чтение загрузочного сектора под Windows - Assembler
Требуется считать загрузочный сектор с диска (fdd,hdd,flash,cd) при чтении с флопа всё проходит нормально, но при попытке чтения с любого...


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

Или воспользуйтесь поиском по форуму:
41
Yandex
Объявления
17.12.2012, 22:40
Ответ Создать тему
Опции темы

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