[英]file size and buffer overshoot
我有一個函數,可以從SD卡打開文件,使用文件大小來設置緩沖區的大小,將信息塊寫入該緩沖區,然后對該信息執行某些操作,如以下代碼所示:
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())
的最后一個循環時, while(f.available())
該循環中讀取文件的末尾,然后繼續讀取緩沖區,緩沖區的末尾充滿了來自最后一個循環的數據,最新的f.read()
並沒有覆蓋這f.read()
。 如何確保while(f.available())
函數的最后一個循環僅適用於當前循環中寫入緩沖區的信息? 現在,我唯一的想法是解決文件大小的因素,並將緩沖區大小設置為小於3072的最大因素,但這在每次調用此函數時都非常費力。 有一個優雅的解決方案盯着我嗎?
您的程序行為不正確,因為不能保證f.read()
能讀取整個緩沖區。 此外,除非文件大小是緩沖區大小的一個因素(在您的情況下為3072),否則在讀取文件的最后一塊時必定會發生這種情況。
盡管Arduino規范( https://www.arduino.cc/en/Reference/FileRead )並未這樣說,但SD.read
函數返回讀取的字節數。 在此處查看庫代碼: https : 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];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.