Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.72/89: Рейтинг темы: голосов - 89, средняя оценка - 4.72
Эксперт С++
 Аватар для Maxim Prishchepa
1936 / 1048 / 109
Регистрация: 29.03.2010
Сообщений: 3,167

Qt быстрая запись в файл

10.09.2010, 10:26. Показов 18814. Ответов 39
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, столкнулся с такой незатейливой проблемой, требуется записывать приходящие от прибора данные в бинарный файл, данные приходят 5-10 раз в секунду, теперь вот думаю как бы правильнее организовать логирование данных в данном случае. Имя файла должно меняться каждый час, т.е. каждый час команды должны записываться в новый файл, и каждый день в новую папку. в общем как - то так.
ЗЫ: ОС - Windows XP (возможно _nix).
Есть подозрение, что если просто открыть файл и гадить в него данные, то этого будет достаточно, т.к. ОС/Qt не дураки и кто нибудь из них обязательно создаст буфер для файла. но хотелось бы всё таки уточнить у знающих людей, может был уже опыт.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.09.2010, 10:26
Ответы с готовыми решениями:

Быстрая запись в файл
Здравствуйте. У меня такой вопрос Каждую милисекунду гарантировано отсылается пакет, который я ловлю, как-то обрабатываю и потом...

Быстрая запись в файл
В общем первым распишу задачу: Нужно записывать в csv файл (UTF8) промежуток цифровых значений по порядку с определённым шагом......

Быстрая запись в БД
Как записать в БД List по быстрее? Иcпользую метод - но для 300 записей уходит 20 секунд. ContentValues cv = new ContentValues(); ...

39
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
11.09.2010, 21:38
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от niXman Посмотреть сообщение
поясню: man 1 time
Тогда другой вопрос - как хорошие таблетки от склероза называются?
И действительно fread/fwrite быстрее работает

За то с mmap выглядит намного загадочнее...
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.09.2010, 21:40
везде в доке пишут, что open() используется для небуферизируемого ввода-вывода.
так же, прототип sync() не принимает дескриптор, что говорит о том, что он не оперирует каким-то конкретным дескриптором. и вообще, в нынешних(не самых старых) версиях glibc, он deprecated.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 21:40
Цитата Сообщение от niXman Посмотреть сообщение
возможно. я лишь пишу то, что знаю.
Ты пишешь, скорее, что не знаешь, говоря "нет".
Цитата Сообщение от niXman Посмотреть сообщение
или fflush()
Ее я и имел ввиду. Опечатался. Так вот при работе с сишной либой данные проходят в общем случае три буфера: буфер glibc, буфер ядра, буфер диска (если есть)
При работе с системными вызовами два: буфер ядра, буфер диска (если есть).
Так что, утверждение, что системные open не буферизуются - неверно. Даже если представить, что я не знаю, как оно работает, то подумал бы, что смысла в системном вызове sync не было бы. Но он sync есть. А синкает он данные из буфера ядра в дисковый буфер (если он есть)
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.09.2010, 21:43
Цитата Сообщение от easybudda Посмотреть сообщение
как хорошие таблетки от склероза называются?
рыба.

Цитата Сообщение от easybudda Посмотреть сообщение
За то с mmap выглядит намного загадочнее...


Добавлено через 28 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
Так вот при работе с сишной либой данные проходят в общем случае три буфера: буфер glibc, буфер ядра, буфер диска (если есть)
При работе с системными вызовами два: буфер ядра, буфер диска (если есть).
Так что, утверждение, что системные open не буферизуются - неверно. Даже если представить, что я не знаю, как оно работает, то подумал бы, что смысла в системном вызове sync не было бы. Но он sync есть. А синкает он данные из буфера ядра в дисковый буфер (если он есть)
пусть так... покопаюсь - отпишусь.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 21:44
Цитата Сообщение от niXman Посмотреть сообщение
так же, прототип sync() не принимает дескриптор, что говорит о том, что он не оперирует каким-то конкретным дескриптором. и вообще, в нынешних(не самых старых) версиях glibc, он deprecated.
Во-первых, sync это системный вызов, он не в glibc. Выполняется он в ядре.
Цитата Сообщение от niXman Посмотреть сообщение
везде в доке пишут, что open() используется для небуферизируемого ввода-вывода.
Возможно, это книжки по прикладному программированию. Соответственно на прикладном-то уровне буфера нет! Поэтому и пишут, что не буферизованный. Значит они ошибаются. В книжках по написанию драйверов и системному программированию вопросу буферизации ввода-вывода уделяется внимание и этот вопрос по-нормальному расписывается.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
11.09.2010, 21:45
кстати, если
C
1
if ( msync(bufOut, nPageSize, MS_INVALIDATE) == -1 ){
поменять на
C
1
if ( msync(bufOut, nPageSize, MS_ASYNC) == -1 ){
получится
Code
1
real    1m1.288s
но всё равно больше, чем с fread
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 21:46
niXman, можешь поискать инфу про dirty pages, pdflush, тогда убедишься, он есть )) и системные вызовы еще как буферизуются.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.09.2010, 21:52
Vourhey, да, по поводу sync() вы правы. он ставит буферы ядра в очередь на запись.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 21:56
niXman, правда, для работы с файлами все равно лучше использовать fopen и т. д., так как они могут пользовательский буфер делать кратным секторам на диске, что, конечно, повысит производительность. В этом я с тобой согласен. Просто хотел поправить по системным вызовам. А то мало ли че )) знаниями нуна делиццо.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.09.2010, 21:56
так же, в книжке говорится, что sync() ставит ВСЕ буферы ядра, всех процессов, в очередь на запись. и так же говориться, что в приложении ее вызывать не хорошо. для сброса буферов конкретного дескриптора, следует применять fsync() или fdatasync(). вот
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 21:59
Цитата Сообщение от niXman Посмотреть сообщение
так же, в книжке говорится, что sync() ставит ВСЕ буферы ядра, всех процессов, в очередь на запись. и так же говориться, что в приложении ее вызывать не хорошо. для сброса буферов конкретного дескриптора, следует применять fsync() или fdatasync(). вот
ну так я разве с этим спорил ))) я просто взял любую функцию, чтобы спросить тебя, что же там за буфер синкается )) Все верно. В программах лучше применять fsync, а sync оставлять для глобальных вещей. А еще лучше дождаться пока ядро само сбросит грязные страницы на диск. Оно само знает, когда ему удобнее.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
11.09.2010, 22:00
все верно.

Добавлено через 22 секунды
я просто дополнил. по теме ведь.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
11.09.2010, 22:02
niXman,
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,980
11.09.2010, 23:30
До меня дошло, почему копирование файлов с отображением в памяти медленнее работает - засада вот, где:
C
1
memcpy(bufOut, bufIn, nPageSize);
При копировании с fread/fwrite куда данные читаются, оттуда и пишутся. Кстати, если использовать read/write - разницы с fread/fwrite практически нет:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
 
int main(int argc, char ** argv){
    int fdIn, fdOut;
    char buf[BUFSIZ];
    ssize_t ret, cnt;
    struct stat st;
    
    if ( argc < 3 ){
        fprintf(stderr, "Usage: %s <src_file> <dst_file>\n", argv[0]);
        exit(1);
    }
    
    if ( ( fdIn = open(argv[1], O_RDONLY) ) == -1 ){
        perror("open");
        exit(1);
    }
    
    if ( fstat(fdIn, &st) == -1 ){
        perror("fstat");
        exit(1);
    }
    
    if ( ( fdOut = creat(argv[2], st.st_mode & ~S_IFMT) ) == -1 ){
        perror("creat");
        exit(1);
    }
    
    cnt = 0;
    while ( ( ret = read(fdIn, buf, BUFSIZ) ) > 0 ){
        if ( write(fdOut, buf, ret) != ret ){
            perror("write");
            exit(1);
        }
        cnt += ret;
    }
    
    close(fdIn);
    close(fdOut);
    
    if ( cnt != st.st_size ){
        fprintf(stderr, "%s: error while reading file %s\n", argv[0], argv[1]);
        exit(1);
    }
    fprintf(stderr, "%s: %d bytes copyed.\n", argv[0], cnt);
    exit(0);
}
Code
1
2
3
4
5
6
7
andrew@debnout:~/cpp/system$ time ./wobuf_copy qt-sdk.bin qt-sdk2.bin 
./wobuf_copy: 367662608 bytes copyed.
 
real    0m56.594s
user    0m0.020s
sys 0m1.892s
andrew@debnout:~/cpp/system$
Правильно Evg сказал:
Цитата Сообщение от Evg Посмотреть сообщение
Время работы записи в файл срадствами ОС (т.е. в конечном итоге системный вызов ядра) будет заведомо больше времени работы любой системы буфферизации.
Но!.. Возвращаясь к задаче, которую ТС поставил, думаю - решение с mmap всё-таки быстрее будет, если данные с прибора сразу в отображённую память читать...
0
Эксперт С++
 Аватар для Maxim Prishchepa
1936 / 1048 / 109
Регистрация: 29.03.2010
Сообщений: 3,167
13.09.2010, 11:09  [ТС]
Ура! товарищи!!! я развязал Холли Вар!!!!
по поводу вызова функции flush() - я от этого отказался, а не происходила запись на диск (да же при закрытии программы), т.к. я начал мудрить и реализовывать патер "одиночка", а вызвать удаление - естественно забыл, в результате - память выделяется, но не очищается, в общем отказался я от всяких там одиночек, сделал всё по людски и о чудо - всё заработало :-)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.09.2010, 12:35
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от niXman Посмотреть сообщение
везде в доке пишут, что open() используется для небуферизируемого ввода-вывода
Вроде тут разобрались, но до кучи попробую пояснить так, чтобы прочим читателям было понятно

Во всех документациях по библиотечным функциям если говорится про буфферизацию, то речь идёт только о буфферизации на уровне библиотеки libc. Т.е. в этом случае данные задерживаются в буффере, который организован в библиотеке и при необходимости сбросить буффер, данные отдаются ядру. Здесь происходит буфферизация внутри одного исполняемого процесса. Т.е. если программа сначала пишет в файл, а потом читает из него (не закрывая файл), то может произойти так, что вся работа по чтению данных пройдёт исключительно из библиотечного буффера. Но если какой-то другой процесс попытается в это время обратиться к файлу, то он этих данных не увидит.

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

Третий уровень - на уровне аппаратуры. Каждый диск имеет свой внутренний буффер, который работает по тому же принципу, как и оба вышестоящих уровня. Т.е. ядро, обращаясь к диску, записывает и получает данные, но где они хранятся в аппаратуре: в буффере или на носителе - ядру неизвестно
7
Эксперт С++
 Аватар для Maxim Prishchepa
1936 / 1048 / 109
Регистрация: 29.03.2010
Сообщений: 3,167
13.09.2010, 13:45  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Вроде тут разобрались, но до кучи попробую пояснить так, чтобы прочим читателям было понятно

Во всех документациях по библиотечным функциям если говорится про буфферизацию, то речь идёт только о буфферизации на уровне библиотеки libc. Т.е. в этом случае данные задерживаются в буффере, который организован в библиотеке и при необходимости сбросить буффер, данные отдаются ядру. Здесь происходит буфферизация внутри одного исполняемого процесса. Т.е. если программа сначала пишет в файл, а потом читает из него (не закрывая файл), то может произойти так, что вся работа по чтению данных пройдёт исключительно из библиотечного буффера. Но если какой-то другой процесс попытается в это время обратиться к файлу, то он этих данных не увидит.

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

Третий уровень - на уровне аппаратуры. Каждый диск имеет свой внутренний буффер, который работает по тому же принципу, как и оба вышестоящих уровня. Т.е. ядро, обращаясь к диску, записывает и получает данные, но где они хранятся в аппаратуре: в буффере или на носителе - ядру неизвестно
Благодарю за инфу, познавательно. На сколько я понимаю, такие методы буферизации, а именно: буферизация уровня библиотеки и ядра - это относится к nix-оподобным ОС, или в Windows такое то же присутствует?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.09.2010, 13:59
Буфферизация уровня библиотеки скорее всего есть на всех системах (на винде точно есть). На уровне ядра - точно сказать не могу.

Буфферизация на уровне ядра - она опасная в том плане, что если машина аварийно отключилась, то рискуем потерять данные, потому как у пользователя нет возможности заставить ядро сбросить буффера на диск. Процедура fflush сбрасывает лишь библиотечный буффер в ядро. Системного вызова flush (который заставил бы ядро сбросить буффер на диск) я что-то не нашёл. А потому есть предположение, что в ядре буфферизация делается короткая. Т.е. процесс отдал ядру данные, ядро их запомнило и поставило исполняться процесс дальше. А затем потихонечку в асинхронном режиме перегонит эти данные на диск. Если они и в правду так, то под виндами логично предположить наличие подобной буфферизации

Подозреваю, что буфферизация на диске так же имеет небольшое время жизни. По тем же соображениям
2
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
17.09.2010, 14:01
Цитата Сообщение от Evg Посмотреть сообщение
Системного вызова flush (который заставил бы ядро сбросить буффер на диск) я что-то не нашёл.
Это fsync или sync, которые упоминались выше.
Цитата Сообщение от Evg Посмотреть сообщение
А потому есть предположение, что в ядре буфферизация делается короткая. Т.е. процесс отдал ядру данные, ядро их запомнило и поставило исполняться процесс дальше. А затем потихонечку в асинхронном режиме перегонит эти данные на диск.
В общем-то верно. На линухе мы также можем управлять сроком жизни грязных буферов в ядре. То есть, если ядро слишком потихонечку перегоняет буфер на девайс, то по истечению определенного времени оно будет обязано это сделать. Эти параметры можно менять здесь: /proc/sys/vm/
Цитата Сообщение от Evg Посмотреть сообщение
Буфферизация на уровне ядра - она опасная в том плане, что если машина аварийно отключилась, то рискуем потерять данные
Ну, тут просто всегда стоит выбор: либо пусть система жрет проц при каждой записи (если данных много и каждый раз выполнять синк), либо пусть ядрышко само решит, когда лучше сделать свое грязное дело.
Цитата Сообщение от Evg Посмотреть сообщение
потому как у пользователя нет возможности заставить ядро сбросить буффера на диск.
Если пользователю очень надо, что он прям не знает куда деваться, то есть команда sync (man 8 sync в помощь)
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
17.09.2010, 14:58
По части sync и /proc/sys/vm/ - значит у пользователя есть почти нормальная возможность управлять ядром по части сброса буфферов. Таким образом второй уровень буфферизации (на уровне ядра) является по сути безопасным. Безопасным в том плане, что пи любом способе буфферизации имеется риск и на этом уровне он такой же, как и на первом. И скорее всего когда ядро сбрасывает буффера на диск, оно имеет возможность "попросить" диск не держать данные в своём аппаратном буффере.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.09.2010, 14:58

Быстрая запись в БД
Здравствуйте! Пишу на Builder c++ - использую firebird. по dde принимаю большой объем данных порядка 500000 в день, Все это мне нужно...

Быстрая запись строк в базу
Есть вот такой кодик: Number($('#count').html()) + 1; $('#count').html(count); $('#found').append(hash+''); Он выводит на html...

Быстрая запись из List в базу данных
Добрый день! На работе решили изобрести велосипед, я сделал, но он получился медленный. Суть дела: Предприятие решило запустить...

Быстрая запись большого колличества данных на питоне
Есть формиловалка ods документа через ooolib. Есть у нас 500 к элементов. Допустим одинаковых строк вида some_str =...

Самая быстрая возможность произвести быструю перезапись в файл.
Подскажите самую быструю возможность произвести быструю перезапись текстового файла. php v4.3.4


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru