gpt4 book ai didi

c++ - 文件大小和缓冲区过冲

转载 作者:行者123 更新时间:2023-11-28 01:33:52 25 4
gpt4 key购买 nike

我有一个从 SD 卡打开文件的函数,使用文件大小来设置缓冲区的大小,将一 block 信息写入该缓冲区,然后使用该信息执行某些操作,如以下代码所示:

char filename = "filename.txt";
uint16_t duration;
uint16_t pixel;
int q = 0;
int w = 0;
bool largefile;
File f;
int readuntil;
long large_buffer;

f = SD.open(filename);

if(f.size() > 3072) {
w = 3072;
} else {
w = f.size();
}
uint8_t buffer[w];

while(f.available()) {
f.read(buffer, sizeof(buffer));

while(q < sizeof(buffer)) {
doStuffWithInformation(buffer[q++]);
}
q=0;
}
f.close;

这适用于较小的文件大小,但超过硬限制缓冲区大小 3072(我根据经验得出,它只是可以安全地提交给此函数的内存量)的任何内容都会遇到问题。较大的文件读取良好,直到它们到达 while(f.available()) 的最后一个循环,在那里它们读取文件的末尾,但随后继续读取缓冲区,缓冲区的尾端被填充使用来自上一个循环的数据,不会被最新的 f.read() 覆盖。如何确保 while(f.available()) 函数的最后一个循环仅使用当前循环期间写入缓冲区的信息?我现在唯一的想法是解决文件大小的因素,并将缓冲区大小设置为小于 3072 的最大因素,但这似乎每次调用此函数时都运行起来很费力。有一个优雅的解决方案吗?

最佳答案

您的程序运行不正常,因为不能保证 f.read() 读取整个缓冲区。此外,当您读取文件的最后一 block 时,它必然会发生,除非文件大小是缓冲区大小的一个因素(在您的情况下为 3072)。

虽然 Arduino 规范 ( https://www.arduino.cc/en/Reference/FileRead ) 没有这样说,SD.read 函数返回读取的字节数。在此处查看图书馆代码:https://github.com/arduino-libraries/SD/blob/master/src/utility/SdFile.cpp , int16_t SdFile::read(void* buf, uint16_t nbyte)

知道这一点后,您应该按如下方式更改循环(同时将其重写为 for 循环以提高可读性并删除上面的 q 定义):

while(f.available()) {
uint16_t sz = f.read(buffer, sizeof(buffer));

for (uint16_t q = 0; q < sz; ++q) {
doStuffWithInformation(buffer[q]);
}
}

附带说明一下,现在,当您拥有此逻辑时,取消可变长度数组并使用大小为 512 的固定缓冲区(SD 卡上的标准扇区大小)是有意义的。最有可能的是,它在读取方面会产生相同的性能,而在 sizeof 方面会产生更好的性能,这将成为编译时常量而不是运行时计算。这也使您的程序更简单。这使得以下代码成为可能:

f = SD.open(filename);
...
uint8_t buffer[512];

关于c++ - 文件大小和缓冲区过冲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50283768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com