我正在尝试创建一个函数,该函数将从ESP8266上SPIFFS中存储的文本文件中删除一行。我尝试遵循此处https://forum.arduino.cc/index.php?topic=344736.msg2380000#msg2380000处的“空间覆盖”方法,但最后只剩下一行空格。
我的理解是,它应该按以下方式工作,其中-
代表替换空间。有问题的文件在行尾只有\n
。
Before
======
This is a line of text\n
This is another line of text\n
And here is another
Replace line 2 with spaces
==========================
This is a line of text\n
----------------------------\n
And here is another
Desired result
==============
This is a line of text\n
And here is another
我最终得到的是以下内容。
Actual result
=============
This is a line of text\n
\n
And here is another
文件大小也保持不变。
这里是我正在使用的deleteLine
功能。
bool deleteLine (char* path, uint32_t lineNum) {
if (!SPIFFS.begin()) {
Serial.println("SPIFFS failed!");
SPIFFS.end();
return false;
}
File file = SPIFFS.open(path, "r+");
if (!file) {
Serial.println("File open failed!");
file.close();
SPIFFS.end();
return false;
}
uint32_t size = file.size();
file.seek(0);
uint32_t currentLine = 0;
bool lineFound = false;
for (uint32_t i = 0; i < size; ++i) {
if (currentLine == lineNum) {
lineFound = true;
for (uint32_t j = i; j < size; ++j) {
uint32_t currentLocation = j;
char currentChar = (char)file.read();
if (currentChar != '\n') {
file.seek(j);
file.write(' ');
} else {
break;
}
}
break;
}
char currentChar = (char)file.read();
if (currentChar == '\n') {
++currentLine;
}
}
file.close();
SPIFFS.end();
if (lineFound) {
return true;
} else {
return false;
}
}
我在这里做蠢事吗?
我知道我可以做的是创建一个新文件,省略该行来复制原始文件,但是,我正在处理2x个文件(每个文件大约1MB,并且需要1MB的额外空间用于存放临时文件),不理想。
我也对是否有任何方法可以截断文件感兴趣。如果有的话,我可以遍历文件,替换字符以实质上删除所需的行,然后添加文件末尾的字符,或截断以消除文件末尾的垃圾。
您要做的是直接在提供的链接中对文件系统进行低级写入(因此,在具有开源硬件/软件的微控制器上,您可以选择的不仅仅是文件读写,还有更多选择。基于PC的操作系统)。
for(uint8_t i=0;i<32;i++) ch[i]=' ';
尝试替换为
for(uint8_t i=0;i<32;i++) ch[i]='X';
您将看到它有效(至少对我有用)。我使用动态行长=从前\ n到要覆盖的行\ n的字符数。为了安全起见,我检查文件大小。有时我会通过将旧文件重命名为bak来压缩文件,并在将新文件写入SPIFFS时忽略它们来删除所有“空”行。对于最大64kb的大型配置文件,它可以完美工作。