2022-02-15 11:37:31 +01:00
|
|
|
|
#include "utils/FileUtils.h"
|
2021-12-22 23:33:47 +01:00
|
|
|
|
|
2022-01-29 00:23:53 +01:00
|
|
|
|
//данная функция записывает файл из буфера страницами указанного размера
|
|
|
|
|
|
void writeFileUint8tByFrames(const String& filename, uint8_t*& big_buf, size_t length, size_t headerLenth, size_t frameSize) {
|
2022-01-25 22:17:55 +01:00
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "w");
|
|
|
|
|
|
if (!file) {
|
2022-01-29 00:23:53 +01:00
|
|
|
|
Serial.println(F("failed write file uint8tByFrames"));
|
2022-01-28 23:39:03 +01:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
size_t written{headerLenth};
|
|
|
|
|
|
while (length > written) {
|
|
|
|
|
|
size_t size = length - written;
|
2022-01-29 00:23:53 +01:00
|
|
|
|
if (size > frameSize) size = frameSize;
|
2022-01-28 23:39:03 +01:00
|
|
|
|
uint8_t* p = &big_buf[written];
|
|
|
|
|
|
size_t res = file.write(p, size);
|
|
|
|
|
|
if (size != res) {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
written += res;
|
2022-01-29 00:23:53 +01:00
|
|
|
|
yield();
|
2022-01-28 23:39:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
file.close();
|
2022-02-16 00:53:52 +01:00
|
|
|
|
onFlashWrite();
|
2022-01-28 23:39:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-02-09 16:44:44 +01:00
|
|
|
|
// void writeStrValueToJsonFile(const String& filename, String key, String value) {
|
|
|
|
|
|
// String tmp = readFile(filename, 4096);
|
|
|
|
|
|
// if (!jsonWriteStr_(tmp, key, value)) {
|
|
|
|
|
|
// Serial.println(F("failed write json value to file"));
|
|
|
|
|
|
// }
|
|
|
|
|
|
// writeFile(filename, tmp);
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
2022-01-30 17:44:45 +01:00
|
|
|
|
//данная функция читает из файла страницами указанного размера
|
|
|
|
|
|
// void readFileUint8tByFrames(const String& filename, size_t frameSize) {
|
|
|
|
|
|
// String path = filepath(filename);
|
|
|
|
|
|
// auto file = FileFS.open(path, "r");
|
|
|
|
|
|
// if (!file) {
|
|
|
|
|
|
// Serial.println(F("failed read file Uint8tByFrames"));
|
|
|
|
|
|
// return;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// size_t length = file.size();
|
|
|
|
|
|
// size_t read{0};
|
|
|
|
|
|
// while (length > read) {
|
|
|
|
|
|
// size_t size = length - read;
|
|
|
|
|
|
// if (size > frameSize) size = frameSize;
|
|
|
|
|
|
// uint8_t p[size];
|
|
|
|
|
|
// size_t res = file.read(p, size);
|
|
|
|
|
|
// //
|
|
|
|
|
|
// if (size != res) {
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// read += res;
|
|
|
|
|
|
// yield();
|
|
|
|
|
|
// }
|
|
|
|
|
|
// file.close();
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
2022-01-28 23:39:03 +01:00
|
|
|
|
void writeFileUint8tByByte(const String& filename, uint8_t*& payload, size_t length, size_t headerLenth) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "w");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
Serial.println(F("failed write file uint8tByByte"));
|
2022-01-28 00:47:13 +01:00
|
|
|
|
return;
|
2022-01-25 22:17:55 +01:00
|
|
|
|
}
|
2022-01-28 00:47:13 +01:00
|
|
|
|
size_t every = 0;
|
2022-01-25 22:17:55 +01:00
|
|
|
|
for (size_t i = 0; i < length; i++) {
|
|
|
|
|
|
if (i >= headerLenth) {
|
2022-01-28 00:47:13 +01:00
|
|
|
|
every++;
|
2022-01-25 22:17:55 +01:00
|
|
|
|
file.print((char)payload[i]);
|
2022-01-28 00:47:13 +01:00
|
|
|
|
if (every > 256) {
|
|
|
|
|
|
yield();
|
|
|
|
|
|
every = 0;
|
|
|
|
|
|
}
|
2022-01-25 22:17:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
file.close();
|
2022-02-16 00:53:52 +01:00
|
|
|
|
onFlashWrite();
|
2022-01-25 22:17:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-22 23:33:47 +01:00
|
|
|
|
File seekFile(const String& filename, size_t position) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "r");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
SerialPrint(F("E"), F("FS"), F("seek file error"));
|
|
|
|
|
|
}
|
|
|
|
|
|
file.seek(position, SeekSet);
|
|
|
|
|
|
return file;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const String writeFile(const String& filename, const String& str) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "w");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
return "failed";
|
|
|
|
|
|
}
|
|
|
|
|
|
file.print(str);
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
return "sucсess";
|
2022-02-16 00:53:52 +01:00
|
|
|
|
onFlashWrite();
|
2021-12-22 23:33:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-24 00:59:44 +02:00
|
|
|
|
const String addFileLn(const String& filename, const String& str) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "a");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
return "failed";
|
|
|
|
|
|
}
|
|
|
|
|
|
file.println(str);
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
return "sucсess";
|
|
|
|
|
|
onFlashWrite();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-22 23:33:47 +01:00
|
|
|
|
const String readFile(const String& filename, size_t max_size) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "r");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
return "failed";
|
|
|
|
|
|
}
|
|
|
|
|
|
size_t size = file.size();
|
|
|
|
|
|
if (size > max_size) {
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
return "large";
|
|
|
|
|
|
}
|
|
|
|
|
|
String temp = file.readString();
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
return temp;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const String filepath(const String& filename) {
|
|
|
|
|
|
return filename.startsWith("/") ? filename : "/" + filename;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cutFile(const String& src, const String& dst) {
|
|
|
|
|
|
String srcPath = filepath(src);
|
|
|
|
|
|
String dstPath = filepath(dst);
|
|
|
|
|
|
SerialPrint(F("i"), F("FS"), "cut " + srcPath + " to " + dstPath);
|
|
|
|
|
|
if (!FileFS.exists(srcPath)) {
|
|
|
|
|
|
SerialPrint(F("E"), F("FS"), "not exist: " + srcPath);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (FileFS.exists(dstPath)) {
|
|
|
|
|
|
FileFS.remove(dstPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
auto srcFile = FileFS.open(srcPath, "r");
|
|
|
|
|
|
auto dstFile = FileFS.open(dstPath, "w");
|
|
|
|
|
|
uint8_t buf[512];
|
|
|
|
|
|
while (srcFile.available()) {
|
|
|
|
|
|
size_t len = srcFile.read(buf, 512);
|
|
|
|
|
|
dstFile.write(buf, len);
|
|
|
|
|
|
}
|
|
|
|
|
|
srcFile.close();
|
|
|
|
|
|
dstFile.close();
|
|
|
|
|
|
FileFS.remove(srcPath);
|
2022-02-16 00:53:52 +01:00
|
|
|
|
onFlashWrite();
|
2021-12-22 23:33:47 +01:00
|
|
|
|
return true;
|
2022-01-15 23:29:52 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-25 00:45:17 +02:00
|
|
|
|
//функция считает количество строк в файле
|
|
|
|
|
|
size_t countLines(const String filename) {
|
|
|
|
|
|
size_t cnt = -1;
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
auto file = FileFS.open(path, "r");
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
return cnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
file.seek(0, SeekSet);
|
|
|
|
|
|
size_t size = file.size();
|
|
|
|
|
|
size_t psn;
|
|
|
|
|
|
do {
|
|
|
|
|
|
cnt++;
|
2022-09-15 14:02:24 +02:00
|
|
|
|
// или /n тут один знак
|
|
|
|
|
|
file.readStringUntil('\r');
|
2022-08-25 00:45:17 +02:00
|
|
|
|
psn = file.position();
|
|
|
|
|
|
} while (psn < size);
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
return cnt;
|
|
|
|
|
|
}
|
2022-08-24 00:59:44 +02:00
|
|
|
|
|
2022-08-25 00:45:17 +02:00
|
|
|
|
//удаляем файл
|
|
|
|
|
|
void removeFile(const String& filename) {
|
|
|
|
|
|
String path = filepath(filename);
|
|
|
|
|
|
if (FileFS.exists(path)) {
|
|
|
|
|
|
if (!FileFS.remove(path)) {
|
2022-09-14 18:06:40 +02:00
|
|
|
|
SerialPrint("i", "Files", "remove file" + path);
|
2022-08-25 00:45:17 +02:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2022-09-14 18:06:40 +02:00
|
|
|
|
SerialPrint("E", "Files", "file not exist " + path);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void removeDirectory(const String& dir) {
|
|
|
|
|
|
String path = filepath(dir);
|
|
|
|
|
|
if (FileFS.exists(path)) {
|
|
|
|
|
|
if (!FileFS.rmdir(path)) {
|
|
|
|
|
|
SerialPrint("i", "Files", "remove dir" + path);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
SerialPrint("E", "Files", "dir not exist " + path);
|
2022-08-25 00:45:17 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-02-16 00:53:52 +01:00
|
|
|
|
|
2022-08-26 00:01:01 +02:00
|
|
|
|
//очищаем директорию с файлами
|
|
|
|
|
|
void cleanDirectory(String path) {
|
2022-09-14 18:06:40 +02:00
|
|
|
|
String filesList = getFilesList(path);
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
while (filesList.length()) {
|
|
|
|
|
|
String buf = selectToMarker(filesList, ";");
|
|
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
removeFile(buf);
|
|
|
|
|
|
SerialPrint("i", "Files", String(i) + ") " + buf + " => deleted");
|
|
|
|
|
|
|
|
|
|
|
|
filesList = deleteBeforeDelimiter(filesList, ";");
|
2022-08-30 00:23:06 +02:00
|
|
|
|
}
|
2022-08-26 00:01:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-27 00:57:19 +02:00
|
|
|
|
void saveDataDB(String id, String data) {
|
|
|
|
|
|
String path = "/db/" + id + ".txt";
|
2022-08-27 02:29:50 +02:00
|
|
|
|
writeFile(path, data);
|
2022-08-27 00:57:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String readDataDB(String id) {
|
|
|
|
|
|
String path = "/db/" + id + ".txt";
|
|
|
|
|
|
return readFile(path, 2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-15 14:02:24 +02:00
|
|
|
|
void cleanLogs() {
|
|
|
|
|
|
SerialPrint("i", "Files", "cleanLogs");
|
2022-08-31 00:13:45 +02:00
|
|
|
|
cleanDirectory("db");
|
2022-09-08 00:27:38 +02:00
|
|
|
|
//очистка данных всех экземпляров графиков
|
|
|
|
|
|
for (std::list<IoTItem*>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) {
|
|
|
|
|
|
if ((*it)->getSubtype() == "Loging") {
|
|
|
|
|
|
(*it)->cleanData();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-08-31 00:13:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-25 00:45:17 +02:00
|
|
|
|
//счетчик количества записей на флешь за сеанс
|
2022-02-16 00:53:52 +01:00
|
|
|
|
void onFlashWrite() {
|
|
|
|
|
|
flashWriteNumber++;
|
2022-08-27 00:57:19 +02:00
|
|
|
|
// SerialPrint(F("->"), F("FS"), F("write data on flash"));
|
2022-08-27 02:45:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Создаем список файлов каталога, функции от Сергея Третьякова
|
|
|
|
|
|
#if defined(ESP8266)
|
2022-09-14 18:06:40 +02:00
|
|
|
|
String getFilesList8266(String& directory) {
|
|
|
|
|
|
String filesList = "";
|
|
|
|
|
|
auto dir = FileFS.openDir(directory);
|
2022-08-27 02:45:02 +02:00
|
|
|
|
while (dir.next()) {
|
2022-09-14 18:06:40 +02:00
|
|
|
|
String fname = dir.fileName();
|
|
|
|
|
|
if (fname != "") filesList += directory + "/" + fname + ";";
|
2022-08-27 02:45:02 +02:00
|
|
|
|
}
|
2022-09-14 18:06:40 +02:00
|
|
|
|
return filesList;
|
2022-08-27 02:45:02 +02:00
|
|
|
|
}
|
2022-09-14 18:06:40 +02:00
|
|
|
|
#endif
|
2022-08-27 02:45:02 +02:00
|
|
|
|
|
2022-09-14 18:06:40 +02:00
|
|
|
|
#if defined(ESP32)
|
|
|
|
|
|
String getFilesList32(String& directory) {
|
|
|
|
|
|
String filesList = "";
|
2022-09-15 14:02:24 +02:00
|
|
|
|
directory = "/" + directory;
|
2022-09-14 18:06:40 +02:00
|
|
|
|
File root = FileFS.open(directory);
|
|
|
|
|
|
directory = String();
|
2022-08-27 02:45:02 +02:00
|
|
|
|
if (root.isDirectory()) {
|
|
|
|
|
|
File file = root.openNextFile();
|
|
|
|
|
|
while (file) {
|
2022-09-14 18:06:40 +02:00
|
|
|
|
String fname = file.name();
|
|
|
|
|
|
if (fname != "") filesList += fname + ";";
|
2022-08-27 02:45:02 +02:00
|
|
|
|
file = root.openNextFile();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-09-14 18:06:40 +02:00
|
|
|
|
return filesList;
|
2022-08-27 02:45:02 +02:00
|
|
|
|
}
|
2022-09-13 16:39:55 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2022-09-14 18:06:40 +02:00
|
|
|
|
String getFilesList(String& directory) {
|
|
|
|
|
|
#if defined(ESP8266)
|
|
|
|
|
|
return getFilesList8266(directory);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if defined(ESP32)
|
|
|
|
|
|
return getFilesList32(directory);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-13 16:39:55 +02:00
|
|
|
|
#if defined(ESP8266)
|
|
|
|
|
|
bool getInfo(FSInfo& info) {
|
|
|
|
|
|
return FileFS.info(info);
|
|
|
|
|
|
}
|
2022-09-15 14:02:24 +02:00
|
|
|
|
|
2022-09-13 16:39:55 +02:00
|
|
|
|
// Информация о ФС
|
2022-09-15 14:02:24 +02:00
|
|
|
|
IoTFSInfo getFSInfo() {
|
|
|
|
|
|
IoTFSInfo myFSInfo;
|
2022-09-13 16:39:55 +02:00
|
|
|
|
FSInfo buf;
|
|
|
|
|
|
if (getInfo(buf)) {
|
2022-09-15 14:02:24 +02:00
|
|
|
|
size_t totalBytes = myFSInfo.totalBytes = buf.totalBytes; // всего
|
|
|
|
|
|
size_t usedBytes = buf.usedBytes; // использовано
|
2022-09-13 16:39:55 +02:00
|
|
|
|
// size_t maxOpenFiles = buf.maxOpenFiles; // лимит на открые файлы
|
|
|
|
|
|
// size_t blockSize = buf.blockSize;
|
|
|
|
|
|
// size_t pageSize = buf.pageSize;
|
|
|
|
|
|
// size_t maxPathLength = buf.maxPathLength; // лимит на пути и имена файлов
|
|
|
|
|
|
size_t freeBytes = totalBytes - usedBytes;
|
2022-09-15 14:02:24 +02:00
|
|
|
|
float freePer = myFSInfo.freePer = ((float)freeBytes / totalBytes) * 100;
|
2022-09-13 16:39:55 +02:00
|
|
|
|
jsonWriteStr(errorsHeapJson, F("freeBytes"), String(freePer) + "% (" + prettyBytes(freeBytes) + ")");
|
2022-09-15 14:02:24 +02:00
|
|
|
|
|
2022-09-13 16:39:55 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
SerialPrint("E", F("FS"), F("FS info error"));
|
|
|
|
|
|
}
|
2022-09-15 14:02:24 +02:00
|
|
|
|
return myFSInfo;
|
2022-09-13 16:39:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(ESP32)
|
2022-09-15 14:02:24 +02:00
|
|
|
|
IoTFSInfo getFSInfo() {
|
|
|
|
|
|
IoTFSInfo myFSInfo;
|
|
|
|
|
|
size_t totalBytes = myFSInfo.totalBytes = FileFS.totalBytes(); // всего
|
|
|
|
|
|
size_t usedBytes = FileFS.usedBytes(); // использовано
|
2022-09-13 16:39:55 +02:00
|
|
|
|
size_t freeBytes = totalBytes - usedBytes;
|
2022-09-15 14:02:24 +02:00
|
|
|
|
float freePer = myFSInfo.freePer = ((float)freeBytes / totalBytes) * 100;
|
2022-09-13 16:39:55 +02:00
|
|
|
|
jsonWriteStr(errorsHeapJson, F("freeBytes"), String(freePer) + "% (" + prettyBytes(freeBytes) + ")");
|
2022-09-15 14:02:24 +02:00
|
|
|
|
return myFSInfo;
|
2022-09-13 16:39:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|