STM32 и SdFat - Не удается создать файл в каталоге на SD-карте
Я использую библиотеку SdFat.h на STM32 и могу успешно создать файл в корневом каталоге с помощью SD.open("test.txt", FILE_WRITE); но мой код не может создать SD.open("DATA/data_test.txt", FILE_WRITE); в каталоге. Вот фрагмент кода, который успешно создает файл в корне:
String final_book_name = upload_book_name + ".txt";
if (SD.exists(final_book_name.c_str())) {
SD.remove(final_book_name.c_str());
}
tft.println(final_book_name); // This successfully prints "test.txt"
book_file = SD.open(final_book_name, FILE_WRITE);
if (SD.exists(final_book_name.c_str())) {
tft.print("Created file");
} else {
tft.print("Failed to create/replace\nfile!");
}
и вот фрагмент кода, который не может создать файл в каталоге:
if (!SD.exists(DATA_DIR)) {
SD.mkdir(DATA_DIR);
}
String final_book_name = upload_book_name + ".txt";
String book_data_path = DATA_DIR;
book_data_path += "/data_" + final_book_name;
if (SD.exists(book_data_path.c_str())) {
SD.remove(book_data_path.c_str());
}
tft.println(book_data_path); // This successfully prints "DATA/data_test.txt"
File book_data_file = SD.open(book_data_path, FILE_WRITE);
if (SD.exists(book_data_path.c_str())) {
book_data_file.print(upload_book_font);
book_data_file.print("|");
book_data_file.print("0");
book_data_file.close();
} else{
tft.print("Failed to create/replace\ndata file!");
if (SD.exists(final_book_name.c_str())) {
SD.remove(final_book_name.c_str());
}
}
@JingleBells, 👍0
Обсуждение2 ответа
Поскольку вы не указали переменную для DATA_DIR
String book_data_path = DATA_DIR;
book_data_path += "/data_" + final_book_name;
таким образом, ваш результирующий путь выглядит следующим образом
DATA_DIR + "/data_" + final_book_name
ЕСЛИ DATA_DIR ="/"
, то это будет "/" + "/data_" + final_book_name
В качестве подсказки используйте не класс string, а массивы символов
определение
const char[] DATA_DIR = "/books";
char book_data_path [128] = {'\0'};
char final_book_name [13] = {'\0'}; // ЕСЛИ поддержка LFN не используется, то 8.3 !!!
const char upload_book_name[] = "my_book";
strcpy (final_book_name, upload_book_name);
strcat (final_book_name, ".txt");
Serial.println(final_book_name);
Если вам нужны длинные имена файлов ,используйте библиотеку SdFat или включите LFB с помощью библиотеки (для которой требуется около 35% памяти или памяти SdFat (при использовании длинных имен файлов).
ОТРЕДАКТИРУЙТЕ
, поскольку вы используете SdFat, и я не знаю, какая версия/вилка связана с записью в подкаталоги. Пожалуйста, проверьте следующее:
Чтобы проверить, запустите SdFat\примеры\Функции директории
и следите за результатами на своем последовательном мониторе
SdFile.cpp. В строках 782 и 1452 у вас есть (в моей версии):
if (block <= m_vol->cacheBlockNumber()
&& block < (m_vol->cacheBlockNumber() + nb)) {
Рабочий код имеет:
if (m_vol->cacheBlockNumber() <= block
&& block < (m_vol->cacheBlockNumber() + nBlock)) {
Если у вас есть верхняя версия, измените ее, и она будет работать
ОТРЕДАКТИРУЙТЕ 2. Обходите проблемы с ошибочной библиотекой SdFat
Вот код обходного пути
const char DATA_DIR [] = "data";
char final_book_name[128] ={'\0'};
char book_data_path [256] ={'\0'};
if (!SD.exists(DATA_DIR)) {
SD.mkdir(DATA_DIR);
SD.chdir(DATA_DIR);
}
strcpy (final_book_name, upload_book_name);
strcat (final_book_name, ".txt";
String book_data_path = DATA_DIR;
strcpy(book_data_path, "data_");
strcat(book_data_path, final_book_name);
if (SD.exists(book_data_path)) {
SD.remove(book_data_path);
}
SD.mkdir(book_data_path);
SD.chdir(book_data_path);
tft.println(DATA_DIR);
tft.println(book_data_path); // Это успешно печатает "DATA/data_test.txt"
File book_data_file = SD.open(final_book_name, FILE_WRITE);
if (SD.exists(final_book_name)) {
book_data_file.print(upload_book_font);
book_data_file.print("|");
book_data_file.print("0");
book_data_file.close();
} else{
tft.print("Не удалось создать/заменить файл\ndata!");
if (SD.exists(final_book_name)) {
SD.remove(final_book_name);
}
}
DATA_DIR-это "ДАННЫЕ". Я не вижу решения в вашем ответе. Я сделаю свои строки символами, это хорошая идея, но как насчет моей главной проблемы здесь?, @JingleBells
Извините, мне все еще неясно, что я должен делать. Я использую STM32, а не Arduino, и у меня нет последовательного монитора. Я попробую загрузить более новую версию SdFat., @JingleBells
Я скачал новейшую версию SdFat отсюда: https://github.com/greiman/SdFat и запустил его, но по-прежнему не удается создать файл в подкаталоге, @JingleBells
Я мог бы попробовать сделать SD.chdir(DATA_DIR); но я не уверен, как именно это работает и даже если в этом проблема. Я не думаю, что SD.chdir(DATA_DIR); необходим, @JingleBells
Я попытался использовать SD.chdir(DATA_DIR); (насколько я знаю, как его использовать), но это не удалось. (он создал файл в корне, а не в директории), @JingleBells
Используйте мою ПРАВКУ 2 оставьте ее на данный момент такой, какая она есть, @Codebreaker007
"Поскольку вы не хотите исправлять свою явно глючную SD.lib", я никогда этого не говорил. Как мне это исправить, у меня нет последовательного монитора?, @JingleBells
Извините за мой цинизм. Но вы раскрываете информацию шаг за шагом, которая должна быть в вашем вопросе с самого начала.На stm32 вам придется переписать программу для вашего Tft. Итак, вы проверили обходной путь.В STM32 библиотека, как известно, создает проблемы, @Codebreaker007
Я понятия не имею, о чем ты говоришь. Спасибо, что попытались мне помочь. Я посмотрю код, который вы опубликовали, и завтра попытаюсь реализовать некоторые его части. Спасибо за помощь., @JingleBells
Я нашел проблему. Я неправильно создаю папку каталога. Когда я проверил SD-карту с другого устройства, папка с ДАННЫМИ была недействительной, и создание ее вручную работает. Я поищу решение и опубликую обновление.
ОБНОВЛЕНИЕ: https://forum.arduino.cc/index.php?topic=421131.0 Я попробую сделать это завтра, но это, вероятно, решит проблему.
- Режимы открытия файлов на SD-карте Arduino добавление/перезапись
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
- Использование SD-адаптера 5 В в системе 3,3 В
- Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <SD.h>
- DFPlayer для записи на SD-карту
- Как **получить** атрибуты для файлов SD?
- Проблема с STM32 и SDFat lib на другом порту SPI
- Попытка прочитать случайную строку с SD-карты
Попробуй это сделать с помощью
/DATA/test.txt
Я помню, что библиотека SD использует классические имена файлов 8.3 и `data_test.txt-это недействительно, @DataFiddler@DataFiddler Я использую SdFat.h с длинными именами (что позволяет использовать имена до 255 символов), @JingleBells