Удаление строки или символов в начале файла. LittelFS.

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Имею файл /file.txt Добавлять новые данные и считывать их научился.

Не знаю с какой стороны подойти чтоб можно было удалить символы в начале файла до знака';'

Файл содержит примерно следующее: 1023;2;-1;7;-4;2;-8;1;0;3;

Задача удалить первые 7 символов. Тчк с зпт можно заменить на перенос каретки (формат не суть важен). Формат файла: первое значение данные датчика, дальше идет на сколько изменились данные. Таким образом хочу вторую строку заменить на сумму первой и второй строк, после чего первую строку удалить и в конец файла добавить новые данные.

В общем принцип видеорегистратора: пишем измененную информацию после ключевого кадра, когда заканчивается место - удаляем старые данные.

Программа которая просто добавляет новые данные АЦП и выводит содержимое файла в сериал вот:

#include <Arduino.h>
#include "FS.h"
#include "LittleFS.h"
ADC_MODE(ADC_VCC);// Будем измерять напряжение на VCC внутри МК

void printFile(){
uint16_t i=0, N=0, summ=0;
String data;
File file = LittleFS.open("/NewFolder/dataFile.txt", "r+");
      while (file.available()) {
            i++;
            char myChar = file.read();
            if (myChar == ';') {
                N++;            
                Serial.print("№ "+String(N)+ " char " + String(i-data.length()) + "-" + String(i-1) + ":");
                summ+= data.toInt();
                Serial.print(summ);
                Serial.print("\n ");
                data = "";
            }
            else{
                 data +=myChar; 
            }
      }
 file.close();
 if (N >50) {LittleFS.format();}
}

int16_t lastData(){
  uint16_t i=0,  summ=0; String data;
  File file = LittleFS.open("/NewFolder/dataFile.txt", "r");
  while (file.available()) {
        i++;
        char myChar = file.read();
        if (myChar == ';') {
          summ+= data.toInt();
          data = "";
        }
        else{
          data +=myChar; 
        }
  }
  file.close();
  return summ;
}

void addNewDataToFile(int newData){
  newData -= lastData();
  File file = LittleFS.open("/NewFolder/dataFile.txt", "a+");
  file.print(String(newData) + ";");
  file.close();
}

void setup() {
  Serial.begin(115200);
  LittleFS.begin();
  addNewDataToFile(ESP.getVcc());
  printFile();  
 // Serial.println(lastData());
}

void loop() {}

На выходе № ячейки, место символов данных в файле в сжатом виде,:посчитанное значение после расжатия данных.

1 char 1-4:3012
 № 2 char 6-6:3012
 № 3 char 8-9:3010
 № 4 char 11-11:3012
 № 5 char 13-14:3010
 № 6 char 16-16:3012
 № 7 char 18-19:3010
 № 8 char 21-21:3010
 № 9 char 23-24:3009
 № 10 char 26-26:3012

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Регистратор так не делает. Он пишет во множество небольших файлов и затирает старые файлы (а не копается в их содержимом), что и я вам рекомендую делать. 

b707
Offline
Зарегистрирован: 26.05.2017

p-a-h-a пишет:

Не знаю с какой стороны подойти чтоб можно было удалить символы в начале файла до знака';'

Задача удалить первые 7 символов.

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

И да, видеорегистратор так не делает, BOOM выше все верно написал

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Ок. Как сдвинуть адрес начала файла?

Как lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,lfs_soff_t off, int whence); пользоваться?

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Проще всего создать Новый файл и читая из старого - записать в Новый  только нужное. 
А для чего это все? Просто «по тренироваться» или есть конкретная задача?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

как в dbf было, сделай первым символом строки признак, удалена она, или живая.  При чтении просто пропускай удаленные строки. Ну и не забывай раз в неделю делать команду Pack(), просто записывая в новый файл все неудалённые строки.  Бонусом получишь еще и бэкап на всякий случай.  

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Это 'Просто потренироваться'.
Вариант как в dbf интересен.
Ну и полагаю можно во флеше выделить массив ячеек и писать по мере поступления новых данных. По окончании места переписывать первую ячейку и во вторую писать спец символ. Началом чтения тогда будет ячейка после спец символа и по кругу.
А можно заморочиться и попробовать прямым доступом к памяти менять данные в текстовом файле. Потренеруюсь в общем.
Идеальный вариант конечно просто сдвинуть стартовый адресс файла.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Да не получится так, как вы пишите. Ну почему почитать книги по теме ленитесь? Хотя бы как файловые системы устроены и как файлы хранятся? Может в гугле забанили? Ну хотя бы это осмыслите: https://it.wikireading.ru/54643

b707
Offline
Зарегистрирован: 26.05.2017

p-a-h-a пишет:

Ок. Как сдвинуть адрес начала файла?

Как lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,lfs_soff_t off, int whence); пользоваться?

с чего вы взяли, что эта функция двигает начало файла?

Вы не знаете как работает seek? - она сдвигает текущую  позицию чтения или записи ВНУТРИ файла, а не сам файл. Это как закладка в книге - указывает, где вы сейчас читаете.

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

p-a-h-a пишет:
...попробовать прямым доступом к памяти менять данные в текстовом файле.

Так Вам в памяти или в файле? Это разные вещи.

rkit
Offline
Зарегистрирован: 23.11.2016

Перезаписывать строчки в файле во флеш-памяти это рецепт для тормозов. Только создавать новый файл и удалять старый.