Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.128.199.88] |
|
Сообщ.
#1
,
|
|
|
Долгое время я работал с файлами используя потоки наприме: ifstream inf ("data.txt",ios::binary);
Но недавно мне посоветовали что если работать с файлами посредством функции _open (например: inf = _open ("data.txt",_O_WRONLY | _O_BINARY | _O_CREAT) то скорость работы программы увеличится в несколько раз. Так ли это? И есть ли еще более быстрый способ? И последний вопрос: если не использовать потоки, то какой тогда будет аналог функции seekg()/seekp()? |
Сообщ.
#2
,
|
|
|
Можно еще использорвать CFile класс для работы с файлами или fopen ... Что насчет скорости - слоный вопрос, вернее я на него ответа не знаю!
|
Сообщ.
#3
,
|
|
|
Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку).
Пример создания файла 4 Га. 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 функцией? |
Сообщ.
#4
,
|
|
|
Цитата З.Ы. Кстати кто знает как определить длину кластера API функцией? Хм... Может, вычислить? Ну там, размер диска разделить на 2^32... ( Для FAT32 по-моему =) ) Или типа того =) |
Сообщ.
#5
,
|
|
|
Длину кластера можно получить, вызвав ::GetDiskFreeSpace() и умножив lpSectorsPerCluster на lpBytesPerSector
Добавлено Кстати, насчет File Mapping - ничего моментального там не будет, волшебства не бывает. И ясное дело файл загружается в оперативку, просто не весь а те участки что используются в анный момент. Что до скорости, то почти у всех способов она будет примерно одинаковой, если писать код правильно |
Сообщ.
#6
,
|
|
|
Цитата Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку). Хм... а я всегда думал, что доступ к оперативной памяти быстрее, чем к ЖД. Я предпочитаю использовать fstream, т.к. это класс и с ним удобнее работать, чем через fopen, и потому что системно независимый. Хоть под unix, хоть под win. Хотя мне кажется, подчеркиваю слово кажется, если применять WINAPI то работа с файлом будет немного быстрее. |
Сообщ.
#7
,
|
|
|
Цитата Red Devil @ Он тоже, 'системо независимый'. fopen |
Сообщ.
#8
,
|
|
|
Цитата Aver @ Исполmзуй File Mapping. Скорость обращению к файлу и обработка - моментальная(файл не загружается в оперативку). Пример создания файла 4 Га. Не согласен, спрорить лень, обсуждалось не раз. Например: Скорость FlushViewOfFile |
Сообщ.
#9
,
|
|
|
Цитата Aver @ файл не загружается в оперативку загружается, но при обращении к опред. байту. TarasCo, а Рихтер писал, что ф-ции WriteFile/ReadFile реализованы именно через File Mapping! и он же писал о ф-ции FlushViewOfFile, как о "тормозной" и жрущей много ресурсов. |
Сообщ.
#10
,
|
|
|
Цитата Алиса @ TarasCo, а Рихтер писал, что ф-ции WriteFile/ReadFile реализованы именно через File Mapping! а где противоречее? Цитата Алиса @ и он же писал о ф-ции FlushViewOfFile, как о "тормозной" и жрущей много ресурсов. просто обычно содержимое файла кешируется и не скидывается на диск сразу же, по закрытию файла. Файловые буфера будут дозаписаны в режиме т.н lazy writer а. С другой стороны FlushViewOfFile будет дожидаться синхронно окончания асинхронной операции записи на диск, что приведет к перепланировке задач. |
Сообщ.
#11
,
|
|
|
Цитата Алиса @ Рихтер писал, что ф-ции WriteFile/ReadFile реализованы именно через File Mapping! покажи, где он это писал? |
Сообщ.
#12
,
|
|
|
А может лучше не будем отходить от темы?
Какой все таки метод работы с файлами наиболее прост и наиболее быстр? Стоит ли мне свои потоки переписывать на что либо другое? |
Сообщ.
#13
,
|
|
|
Цитата Brunnen-g @ А может лучше не будем отходить от темы? Поиски серебрянной пули - это не тема, а флейм. "Просто и быстро" - обычно противоречат друг другу. Например, чтобы прочитать в массив числа из текстового файла, разделенные пробелами, сложно придумать что-то проще, чем: vector<double> v(istream_iterator<double>(fstream("data.txt")), istream_iterator<double>()); Есть редкие исключения, конечно. Для специфичных задач. Например, некий массив сохранен бинарно в файле (размером несколько сотен мегабайт) и нужно в нем некоторые значения прочитать, некоторые записать, но не все. Вразнобой, к каждому элементу могут как не обращаться, так и десятки раз использовать... В таком случае при использовании MMF противоречия между скоростью и удобством нет. Даже если рассматривать только скорость - тоже многое зависит от задачи. Например, если читать сотни мегабайт бинарных данные большими блоками последовательно, то ReadFile будет наиболее быстрой, особенно, если поиграться флагами в CreateFile. Однако, при чтении небольшими кусками она сольёт абсолютно всем прочим способам, даже форматированному вводу потоков C++. И величина слива будет исчисляться порядками (в случае однобайтных блоков порядков будет много). |
Сообщ.
#14
,
|
|
|
1) Обычно лучше пользоваться fopen/fread/frite для C или fstream-ми для С++, т.к. они буферизируют данные (очень полезно если читаешь/пишешь небольшими порциями).
2) Если читаешь/пишешь большими кусками, кратными размеру блока на файл-системе (16/32/64/... КБ) то можно использовать WinAPI ReadFile/WriteFile. Пожалуй будет чуть побыстрее, т.к. эти ф-ции находятся ближе к моменту системного вызова и меньше кода выполниться на уровне апликации. 3) Мапируюшие ф-ции (MapViewOfFile...) обычно работают медленей обычного чтения, пользоваться ими стоит только если действительно необходимо замапировать файл в память (для простоты доступа например). ЗЫ: Обший принцип вообще-то прост и не зависит от выбранного API: читать/писать последовательно и большими кусками. |