Как изменить значения внутри файла

Я пишу wav-файл на SD-карту на ESP32, и это требует, чтобы каждый раз, когда я добавляю данные в конец файла, я изменял заголовок, чтобы установить правильный размер в некоторых полях.

Я не могу найти, как заменить значение внутри файла, я попытался записать новые значения с помощью функции поиска, но если я не пропущу что-то похожее, это удалит все после добавления нового значения.

Я не хочу создавать новый файл и удалять старый, так как я буду хранить потенциально большие файлы wav и, похоже, тратить ресурсы впустую.

Есть ли способ перезаписать одно значение внутри файла? Я использую SDlib, но я открыт и для других.

Вот код, который я использую для создания файла и его обновления:

#include "WavFileWriter.h"

void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
{
  byte headerBuffer[44];
  wavFileHeader->getHeaderData(headerBuffer);
  File file = SD.open(filename, FILE_WRITE);
  file.write(headerBuffer, 44);
  file.close();
}

void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
{
  File file = SD.open(filename, FILE_WRITE);
  file.write(data, dataLength);

  byte headerBuffer[44];
  wavFileHeader->setFileSize(file.size());
  wavFileHeader->getHeaderData(headerBuffer);

  file.seek(0);
  file.write(headerBuffer, 44);
  file.close();
}

После вызова appendData я получаю файл только с размером заголовка (с правильным заголовком для файла с данными, но данные исчезли).

, 👍0

Обсуждение

зачем вам хранить звуковые данные в формате wav?, @jsotola

можете ли вы определить положение сектора на SD-карте, где хранится заголовок, сохранить его копию в оперативной памяти, обновлять эту копию и время от времени записывать ее на SD-карту?, @imalipusram

просто храните необработанные данные ... если вам нужен wav-файл, используйте что-то вроде Audacity для преобразования raw в wav, @jsotola

покажи свой код., @Juraj

добавил код. Я должен был сделать это с самого начала, моя вина., @Ignacio Soler Garcia

проблема: если у меня есть файл фиксированного размера (в моем случае 8 МБ), и я ищу где -то файл и делаю запись, размер файла усекается до конца блока, который я пишу. Я эмулирую диск с помощью файла и пытаюсь записать "секторные данные" в разных местах. Чтение с использованием той же стратегии работает нормально, но записи уничтожают любые данные после сектора, который я пишу, усекая размер файла. // запуск на ESP32 с использованием среды arduino IDE 1.8.13 // начните с файла с именем CPM000.DSK на SD-карте, которая 256*64*512 bytes #include "FS.h" // поддержка файловой системы #include "SD_MMC.h" // Поддержка USD-карт, @Lawrence Glaister


2 ответа


0

SD.seek () - это API, который вы ищете. Он позволяет расположить указатель чтения/записи в файле. В стандартном C++ используется API fseek ().

,

OP использует seek(), @Juraj

Я добавил код, чтобы вы могли видеть, является ли это ожидаемым использованием., @Ignacio Soler Garcia

Похоже, вы не ищете конец файла, когда пытаетесь добавить данные. Попробуйте: file.seek(file.size()) между SD.open() и файлом.write() в методе WavFileWriter::appendData ()., @Jeff Wahaus


1

FILE_WRITE в библиотеке SD-это "добавить" (по историческим причинам).

#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

так что используйте

 File file = SD.open(filename, O_WRITE);
,

Похоже, ESP32 использует другую библиотеку, и определения разные: #define FILE_READ "r" #define FILE_WRITE "w" #определить FILE_APPEND "a", @Ignacio Soler Garcia

Должен ли я использовать SPIFFS вместо SD?, @Ignacio Soler Garcia