Как из конца файла удалить кусок данных. - страница 3

 
ROMAN KIVERIN:

Не могли бы написать код. Не очень понятно как надо делать. Спасибо.

Как в заголовок файла сохранять в заголовок файла количество записей?

Мне только  надо чтобы последние свечки не отрисовывались в окне терминала. Файл открыт как график.

Код писать не стану, а на словах - вот.

Вы же пишете заголовок, вот Ваш код:

FileWriteInteger(rhandle,400,LONG_VALUE);
FileWriteString(rhandle,"(C)opyright 2019, Roman",64);
FileWriteString(rhandle,Symb,12);
FileWriteInteger(rhandle,frame,LONG_VALUE);
FileWriteInteger(rhandle,Digits,LONG_VALUE);
FileWriteArray(rhandle,voidA,0,15);

Добавьте поле HeaderLen (как это принято, вторым после поля-идентификатора двоичного файла - у Вас это "400"?). И где-то в заголовке добавьте поле RecordLen, где будет длина записи в байтах, и поле RecordsCnt с количеством записей. Для чтения (или коррекции) записи #N устанавливаете указатель на байт N * RecordLen + HeaderLen функцией FileSeek. При добавлении записи в конец обновляете (инкремент) поле RecordsCnt - так же используете FileSeek для установки указателя на поле RecordsCnt и пишете новое значение. Так же действуете для "удаления" последних записей - просто уменьшите на X количество записей и обновите в заголовке. Обрезать конец файла смысла нет, файл всё равно в дальнейшем удлинится.

Обновляйте RecordsCnt в заголовке только после каждого пакета добавлений записей, ну или если в пакете одна запись.

Всё это будет работать очень быстро.

Если у Вас есть ИБП, не используйте FileFlush при добавлении каждой записи, только при массовом добавлении после каждого пакета. И при обновлении RecordsCnt в заголовке. Винда сама делает Flush на диск каждые 5 сек, как правило.

 
Edgar Akhmadeev:

Код писать не стану, а на словах - вот.

Вы же пишете заголовок, вот Ваш код:

Добавьте поле HeaderLen (как это принято, вторым после поля-идентификатора двоичного файла - у Вас это "400"?). И где-то в заголовке добавьте поле RecordLen, где будет длина записи в байтах, и поле RecordsCnt с количеством записей. Для чтения (или коррекции) записи #N устанавливаете указатель на байт N * RecordLen + HeaderLen функцией FileSeek. При добавлении записи в конец обновляете (инкремент) поле RecordsCnt - так же используете FileSeek для установки указателя на поле RecordsCnt и пишете новое значение. Так же действуете для "удаления" последних записей - просто уменьшите на X количество записей и обновите в заголовке. Обрезать конец файла смысла нет, файл всё равно в дальнейшем удлинится.

Обновляйте RecordsCnt в заголовке только после каждого пакета добавлений записей, ну или если в пакете одна запись.

Всё это будет работать очень быстро.

Если у Вас есть ИБП, не используйте FileFlush при добавлении каждой записи, только при массовом добавлении после каждого пакета. И при обновлении RecordsCnt в заголовке. Винда сама делает Flush на диск каждые 5 сек, как правило.

Если честно то ничего не понятно. Можете по проще?

 
ROMAN KIVERIN:

Если честно то ничего не понятно. Можете по проще?

Если честно, это моя большая проблема - объяснять. Нет у меня педагогической жилки. Чтобы получить пользу, надо всё-таки знать основы программирования. 

Попробуйте читать каждое предложение отдельно. Изучить FileSeek. И всё встанет на места. Ну или кто-то более толково и умно объяснит. А то и напишет готовый код. Но тогда Вы не научитесь [быстро].

 
Не тот ли это случай, когда от файлов пора переходить к БД?
 
Aleksey Nikolayev:
Не тот ли это случай, когда от файлов пора переходить к БД?

Может быть и да, вот может лучше сейчас этот вопрос доделать как есть. Потом мне ничего искать не надо нужно только двигаться в зад и вперед по файлу. Очень простая задача. Не думаю что её нужно как-то сложно решать.

 
Edgar Akhmadeev:

Если честно, это моя большая проблема - объяснять. Нет у меня педагогической жилки. Чтобы получить пользу, надо всё-таки знать основы программирования. 

Попробуйте читать каждое предложение отдельно. Изучить FileSeek. И всё встанет на места. Ну или кто-то более толково и умно объяснит. А то и напишет готовый код. Но тогда Вы не научитесь [быстро].

Если честно, то этот вопрос никогда не был предметом обучения. За свою жизнь я всего пару раз писал операции с файлами и думаю есть люди, которые смогут предметно показать как решить этот вопрос. По моему здесь нет ничего сложного и знает этот вопрос. 

 
Aleksey Nikolayev:
Не тот ли это случай, когда от файлов пора переходить к БД?

Не в этом случае. Здесь идёт строго последовательная информация, ключ каждой записи - дата, и добавляются эти записи  не вразброс, а последовательно. При этом, если используется индексация по дате, то в двоичном дереве появляется ветка бесконечной длины, индекс не сбалансирован. Чтобы этого избежать, движок БД при добавлениях записей постоянно перестраивает структуру, балансируя индекс, и этот процесс очень медленный.

 
ROMAN KIVERIN:

Ренат. Около нескольких миллионов записей. Так их туда сюда гонять будет не просто.

да, не подходит такое.

а может быть переместиться в конец файла, откатиться назад на нужное количество строк,

к оставшимся снизу строкам применить функцию

https://www.mql5.com/ru/docs/strings/stringtrimleft

затем почистить весь получившийся кусок текста и сохранить файл

то есть из нескольких строк сделать одну и поменять на пустую строку

не пробовал, но предполагаю что поможет

Документация по MQL5: Строковые функции / StringTrimLeft
Документация по MQL5: Строковые функции / StringTrimLeft
  • www.mql5.com
Строковые функции / StringTrimLeft - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Simakov:

kernel32.dll

Только и файл создавать/править, тоже через winapi нужно будет. Так, что изучайте)

https://docs.microsoft.com/ru-ru/windows/win32/api/fileapi/

Спасибо большое. Что-то никак не получается открыть файл средствами winapi.

Не можете написать несколько строк как использовать

SetFilePointer(handle, pointerWhatYouWant, &temp, FILE_BEGIN);
SetEndOfFile(handle); 

SetFileValidData(handle, pointerWhatYouWant);

эту функцию.

Как я понимаю можно один и тот же файл открывать средствами WinApi и MQL? И работать с ним одновременно с помощью MQL и WinApi.

 

как вариант: можно сделать недо-базу :-) когда пишется громадный файл с большими записями (даже с переменным размером, например со строками, даже CSV) - пишите рядом индексный файл с фиксированными записями первичный_ключ:смещение:размер;

свечки очевидно и естественно сразу сортированы по времени, потому что они физически так поступают; процедура удаления любых/произвольных свечек будет выглядеть как обнуление поля "размер" в индексе.

если удаления часты, потребуется отдельная процедура squeeze - раз в неделю (например в ночь с сб на вск) перелопатить оба файла

PS/ в реальной жизни примерно так видео пишется во всяких DVR, рядом ведётся индексный файл по опорным кадрам.