簡體   English   中英

文件大小和緩沖區過沖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM