SdFat. Удаление строки из txt. Вставить текст в середину или начало
- Войдите на сайт для отправки комментариев
Всем привет!. Заранее предупреждаю: я малость тупой.
Есть у меня Sd карта на 8гб FAT32, и ардуино Due. Использую библиотеку SDFat. Задача следующая:
есть файл, с настройками например, типа:
name = Илья IDcart = 2268284959 password = 7524 dostup_mode = 0 lv0_coutn = 5 lv0_chance = 50
Парсинг проблем не вызывает. Но мне хочется еще и менять настройки. Например password задать 12345678. write и print затирают старые символы, а мне нужно удалить все между '=' и '\n'. Я не нашёл метода, что бы делал это(Вообще я не нашёл описания методов для SDfat, только для SD. Буду рад если кто-нибудь поделется ссылочкой, если такая имеется), поэтому приступил к написанию своих функций. С вставкой я справился хоть и не оптимально. Приходится пробегать по всему файлу по байту. Если файл маленький, то не критично, но а вдруг нет? А как удалять вообще не представляю. Вот что я имею. Тесты провожу на файле с :
Hello, world!!! Test file.
На выходе:
String123456789, world!!! Test file. le.
Код:
#include "SdFat.h"
SdFat SD;
const int chipSelect = 4;
// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(chipSelect, DEDICATED_SPI, SD_SCK_MHZ(16))
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(chipSelect, SHARED_SPI, SD_SCK_MHZ(16))
#endif // HAS_SDIO_CLASS
void insert(File &file, char * str, unsigned long poz){
unsigned long len = strlen(str), siz=file.size();
char c;
file.seek(siz);
for (unsigned long i = 0; i=poz and i!= 0xFFFFFFFF ); i--){
file.seek(i);
c = file.peek();
Serial.println(c);
file.seek(i+len);
file.write(c);
}
file.seek(poz);
file.write(str, len);
}
void insert(File &file, String &str, unsigned long poz){
unsigned long len = str.length(), siz=file.size();
char c;
file.seek(siz);
for (unsigned long i = 0; i=poz and i!= 0xFFFFFFFF ); i--){
file.seek(i);
c = file.peek();
file.seek(i+len);
file.write(c);
}
file.seek(poz);
file.write(str.c_str(), len);
}
void removetxt(File &file, unsigned long pos, unsigned long count){
unsigned long siz=file.size();
char c;
for (unsigned long i = pos+count; i < siz; i++) {
file.seek(i);
c = file.peek();
file.seek(i-count);
file.write(c);
}
//как удалить count последних символов из файла???
}
void setup() {
Serial.begin(9600);
while ( !SD.begin( SD_CONFIG )) {
Serial.println("initialization failed!");
delay(1000);
}
Serial.println("initialization OK!");
File myFile = SD.open("tasks/test1.txt", FILE_WRITE);
if (myFile) {
unsigned long s = myFile.size();
unsigned long p = myFile.position();
Serial.println(s);
Serial.println(p);
insert(myFile, "123456789", 0); // Вставим в начало
String my_s = "String";
insert(myFile, my_s, 0); // Вставим в начало
removetxt(myFile, 15, 5); // удаляем слово Hello
myFile.close();
} else Serial.println("open failed!");
}
void loop() {}
Пишешь новый файл с нуля, переименуешь его на место старого.
Пишешь новый файл с нуля, переименуешь его на место старого.
А можно с примерчиком?
Ок. Побежал покупать оборудование, собирать, писать и отлаживать тебе примерчик. Жди.
А можно с примерчиком?
А можно 800р?
Я просто не представляю как создать пустой файл, заполнить его и лишь потом его сохранить с нужным именем. Я могу сохранить новый файл, например test2.txt. Сделать там всё что нужно. Сохранить. Удалить исходник. Скопировать с нужным именем и удалить test2.txt. Ну как то... Кажется вы не это имели в виду. И если подгружать весь файл в оперативку, а он скажем 1000 строк, хватит ли оперативки?
Короче меня интересует лишь как создать файл не повредив исходник и только в конце их пересохранить.
Приведенный вами пример с ошибками и не компилируется.
Короче меня интересует лишь как создать файл не повредив исходник и только в конце их пересохранить.
Если не хотите создавать второй файл в памяти чтоб его сохранить, а затем удалить исходник и переименовать вновь созданный файл, попробуйте другой алгоритм.
Т.к. у Вас файл настроек имеет статичный характер "параметр" = "значение" значит нужна самописная функция, которая способна сформировать такую строку целиком и записать ее в файл.
Вы используете String, поэтому пример будет содержать этот класс.
эта функция должна принимать параметры: имя файла настроек, параметр, новое значение параметра.
далее открываем файл настроек (имя файла настроек), открываем временный файл, проверяем открылись ли, если нет кричим в терминал ошибку - где затык, вываливаемся из функции с возвратом false. Если все хорошо, в цикле пока есть что читать начинаем читать построчно файл настроек, парсим каждую строку на предмет наличия параметра, если параметр найден, заменяем прочитанную строку новой с новым параметром, и записываем ее во временный файл, если строка с параметром не найдена, то оставляем прочитанную строку без изменений и пуляем ее во временный файл. Всё, все строки закончились, закрываем оба файла. Проверяем был ли найден параметр, если нет, то вываливаемся с ошибкой. Если был найден, пытаемся удалить уже старый файл настроек, если все хорошо, пытаемся переименовать временный файл в файл с именем "имя файла настроек" если все хорошо, то выходим из функции с возвратом true. Как-то так...
Внимание!!!, нижеприведенный пример НЕ проверялся на корректность, правильность, грамотность, оптимальность, а был написан на скорую руку, на коленке быдлокодом. Скорее всего в примере есть ошибки, прошу Вас проверить работоспособность, т.к. на данный момент нет карточки и железа под рукой.
Пример:
bool update_settings(String settings_file_name, String argument, String value){ bool ret = false; File settingFile = SD.open(settings_file_name, FILE_READ); if (!settingFile){ Serial.println("Error: settings file not found, or card error !"); return false; } File tmpFile = SD.open("/tmp_settings.txt", FILE_WRITE); if (!tmpFile){ Serial.println("Error: can't create tmp_settings.txt. Write protect?, No free space ?"); return false; } while(settingFile.available()){ String tmp_str = settingFile.readString(); if (tmp_str.indexOf(argument) > -1) { ret = true; tmp_str = argument + " = " + value; Serial.println("OK, argument found."); } tmpFile.println(tmp_str); } settingFile.close(); tmpFile.close(); if (!ret) { Serial.println("Error: argument not found. !"); SD.remove("/tmp_settings.txt"); return false; } if (!SD.remove(settings_file_name)) { Serial.println("Error with remove old settings file ! Write protect ?"); return false; } if (!SD.rename("/tmp_settings.txt", settings_file_name)){ Serial.println("Error with rename tmp settings file ! Write protect ?"); return false; } rerurn true; }Данный пример предполагает, что строчки " параметр = значение" расположены строго на отдельных строчках, а если это не так - будет тыква
само собой будет тыква ))) я просто ориентировался на файл настроек автора темы.
По секрету скажу, что в реальной задаче настройки уже загружены в память.
Ну я других ошибок не искал... Сижу в магазине жену жду, она пошла что-то мерять, это надолго:)
[/quote]
SD.rename
[/quote]
в библиотеке нет такой функции
Можно ли создать новый пустой файл, сначала скопировать оригинал, затем удалить исходный файл, а затем изменить его имя?