Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > Visual C++ / MFC / WTL > Самый быстрый способ работы с файлами |
Автор: Brunnen-g 17.04.06, 19:31 |
Долгое время я работал с файлами используя потоки наприме: ifstream inf ("data.txt",ios::binary); Но недавно мне посоветовали что если работать с файлами посредством функции _open (например: inf = _open ("data.txt",_O_WRONLY | _O_BINARY | _O_CREAT) то скорость работы программы увеличится в несколько раз. Так ли это? И есть ли еще более быстрый способ? И последний вопрос: если не использовать потоки, то какой тогда будет аналог функции seekg()/seekp()? |
Автор: bullet 17.04.06, 20:47 |
Можно еще использорвать CFile класс для работы с файлами или fopen ... Что насчет скорости - слоный вопрос, вернее я на него ответа не знаю! |
Автор: Aver 17.04.06, 21:01 |
Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку). Пример создания файла 4 Га. <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> DWORD size = 1024; DWORD tm1 = ::GetTickCount(); HANDLE hFile = ::CreateFile("D:\\444.txt", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 1, size, NULL); BYTE* buf = (BYTE*)::MapViewOfFile(hMap, FILE_MAP_WRITE|FILE_MAP_READ, 0, 1, size); DWORD tm2 = ::GetTickCount(); DWORD res = tm2 - tm1; ::UnmapViewOfFile(buf); ::CloseHandle(hMap); ::CloseHandle(hFile); Но лучше всего(если файлы >> 4 Га) обрабатывать блоками и блоки брать длиной кластера. З.Ы. Кстати кто знает как определить длину кластера API функцией? |
Автор: Hsilgos 17.04.06, 21:58 |
Цитата З.Ы. Кстати кто знает как определить длину кластера API функцией? Хм... Может, вычислить? Ну там, размер диска разделить на 2^32... ( Для FAT32 по-моему =) ) Или типа того =) |
Автор: HOMO_PROGRAMMATIS 17.04.06, 23:23 |
Длину кластера можно получить, вызвав ::GetDiskFreeSpace() и умножив lpSectorsPerCluster на lpBytesPerSector Добавлено Кстати, насчет File Mapping - ничего моментального там не будет, волшебства не бывает. И ясное дело файл загружается в оперативку, просто не весь а те участки что используются в анный момент. Что до скорости, то почти у всех способов она будет примерно одинаковой, если писать код правильно |
Автор: Red Devil 18.04.06, 04:59 |
Цитата Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку). Хм... а я всегда думал, что доступ к оперативной памяти быстрее, чем к ЖД. Я предпочитаю использовать fstream, т.к. это класс и с ним удобнее работать, чем через fopen, и потому что системно независимый. Хоть под unix, хоть под win. Хотя мне кажется, подчеркиваю слово кажется, если применять WINAPI то работа с файлом будет немного быстрее. |
Автор: SVK 18.04.06, 06:37 |
Он тоже, 'системо независимый'. |
Автор: TarasCo 18.04.06, 09:58 |
Цитата Aver @ Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку). Пример создания файла 4 Га. Не согласен, спрорить лень, обсуждалось не раз. Например: Скорость FlushViewOfFile |
Автор: Алиса 18.04.06, 10:53 |
загружается, но при обращении к опред. байту. TarasCo, а Рихтер писал, что ф-ции WriteFile/ReadFile реализованы именно через File Mapping! и он же писал о ф-ции FlushViewOfFile, как о "тормозной" и жрущей много ресурсов. |
Автор: TarasCo 18.04.06, 14:11 |
Цитата Алиса @ TarasCo, а Рихтер писал, что ф-ции WriteFile/ReadFile реализованы именно через File Mapping! а где противоречее? просто обычно содержимое файла кешируется и не скидывается на диск сразу же, по закрытию файла. Файловые буфера будут дозаписаны в режиме т.н lazy writer а. С другой стороны FlushViewOfFile будет дожидаться синхронно окончания асинхронной операции записи на диск, что приведет к перепланировке задач. |
Автор: Denny 19.04.06, 07:37 |
покажи, где он это писал? |
Автор: Brunnen-g 21.04.06, 21:57 |
А может лучше не будем отходить от темы? Какой все таки метод работы с файлами наиболее прост и наиболее быстр? Стоит ли мне свои потоки переписывать на что либо другое? |
Автор: Hryak 22.04.06, 07:07 |
Поиски серебрянной пули - это не тема, а флейм. "Просто и быстро" - обычно противоречат друг другу. Например, чтобы прочитать в массив числа из текстового файла, разделенные пробелами, сложно придумать что-то проще, чем: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> Но это будет далеко не самый быстрый способ.vector<double> v(istream_iterator<double>(fstream("data.txt")), istream_iterator<double>()); Есть редкие исключения, конечно. Для специфичных задач. Например, некий массив сохранен бинарно в файле (размером несколько сотен мегабайт) и нужно в нем некоторые значения прочитать, некоторые записать, но не все. Вразнобой, к каждому элементу могут как не обращаться, так и десятки раз использовать... В таком случае при использовании MMF противоречия между скоростью и удобством нет. Даже если рассматривать только скорость - тоже многое зависит от задачи. Например, если читать сотни мегабайт бинарных данные большими блоками последовательно, то ReadFile будет наиболее быстрой, особенно, если поиграться флагами в CreateFile. Однако, при чтении небольшими кусками она сольёт абсолютно всем прочим способам, даже форматированному вводу потоков C++. И величина слива будет исчисляться порядками (в случае однобайтных блоков порядков будет много). |
Автор: Dimach 22.04.06, 07:44 |
1) Обычно лучше пользоваться fopen/fread/frite для C или fstream-ми для С++, т.к. они буферизируют данные (очень полезно если читаешь/пишешь небольшими порциями). 2) Если читаешь/пишешь большими кусками, кратными размеру блока на файл-системе (16/32/64/... КБ) то можно использовать WinAPI ReadFile/WriteFile. Пожалуй будет чуть побыстрее, т.к. эти ф-ции находятся ближе к моменту системного вызова и меньше кода выполниться на уровне апликации. 3) Мапируюшие ф-ции (MapViewOfFile...) обычно работают медленей обычного чтения, пользоваться ими стоит только если действительно необходимо замапировать файл в память (для простоты доступа например). ЗЫ: Обший принцип вообще-то прост и не зависит от выбранного API: читать/писать последовательно и большими кусками. |