Всем привет! Пишу я под ESP32, возможно какое-то значение это имеет. Проблема в том, что SD.exists всегда выдаёт false. Вот код: Код (C++): #include <SPI.h> #include <mySD.h> //Библиотека SD для ESP32 bool SD_Exists(String file){ char cfn[file.length() + 1]; file.toCharArray(cfn, sizeof(cfn)); Serial.println(cfn); return SD.exists(cfn); } void setup() { Serial.begin(115200); SD.begin(5, 23, 19, 18); } void loop() { Serial.println(SD_Exists("OS/3X128/system") ? "Exists" : "NO!"); delay(500); } Вот результат: На карте памяти папка есть, карта подключена к ESP. Подскажите пожалуйста, в чём проблема
Код (C++): #include <SPI.h> #include <mySD.h> bool SD_Exists(String file){ char cfn[file.length() + 1]; file.toCharArray(cfn, sizeof(cfn)); Serial.println(cfn); return SD.exists(cfn); } void setup() { Serial.begin(115200); if(SD.begin(5, 23, 19, 18)){ //Контакты, к которым подключена карта Serial.println("SD.begin() OK"); } } void loop() { Serial.println(SD_Exists("") ? "Exists" : "NO!"); Serial.println(SD_Exists("/") ? "Exists" : "NO!"); delay(500); } Выдаёт
Пришёл к выводу, что всё, кроме exists() работает. Нашёл код в исходниках: Код (C++): boolean walkPath(char *filepath, SdFile& parentDir, boolean (*callback)(SdFile& parentDir, char *filePathComponent, boolean isLastComponent, void *object), void *object = NULL) { /* When given a file path (and parent directory--normally root), this function traverses the directories in the path and at each level calls the supplied callback function while also providing the supplied object for context if required. e.g. given the path '/foo/bar/baz' the callback would be called at the equivalent of '/foo', '/foo/bar' and '/foo/bar/baz'. The implementation swaps between two different directory/file handles as it traverses the directories and does not use recursion in an attempt to use memory efficiently. If a callback wishes to stop the directory traversal it should return false--in this case the function will stop the traversal, tidy up and return false. If a directory path doesn't exist at some point this function will also return false and not subsequently call the callback. If a directory path specified is complete, valid and the callback did not indicate the traversal should be interrupted then this function will return true. */ SdFile subfile1; SdFile subfile2; char buffer[PATH_COMPONENT_BUFFER_LEN]; unsigned int offset = 0; SdFile *p_parent; SdFile *p_child; SdFile *p_tmp_sdfile; p_child = &subfile1; p_parent = &parentDir; while (true) { boolean moreComponents = getNextPathComponent(filepath, &offset, buffer); boolean shouldContinue = callback((*p_parent), buffer, !moreComponents, object); if (!shouldContinue) { // TODO: Don't repeat this code? // If it's one we've created then we // don't need the parent handle anymore. if (p_parent != &parentDir) { (*p_parent).close(); } return false; } if (!moreComponents) { break; } boolean exists = (*p_child).open(*p_parent, buffer, O_RDONLY); // If it's one we've created then we // don't need the parent handle anymore. if (p_parent != &parentDir) { (*p_parent).close(); } // Handle case when it doesn't exist and we can't continue... if (exists) { // We alternate between two file handles as we go down // the path. if (p_parent == &parentDir) { p_parent = &subfile2; } p_tmp_sdfile = p_parent; p_parent = p_child; p_child = p_tmp_sdfile; } else { return false; } } if (p_parent != &parentDir) { (*p_parent).close(); // TODO: Return/ handle different? } return true; } Может быть супер-гуру-профессионалы найдут ошибку?
Я победил эту систему, написав функцию: Код (C++): bool SD_Exists(String file){ char cfn[file.length() + 1]; file.toCharArray(cfn, sizeof(cfn)); Serial.println(cfn); File f = SD.open(cfn, FILE_READ); return f.available() > 0; } Причём, я думал, что это не будет работать для директорий, однако сработало. Я не знаю почему.
Вы наплодили утечек памяти, как минимум. Вашу функцию надо переписать как минимум так: Код (C++): bool SD_Exists(const String& file) { Serial.println(file); File f = SD.open(file.c_str(), FILE_READ); if(f) { bool b = f.available(); f.close(); return b; } return false; } И вообще - ваша мания везде, где не надо, юзать toCharArray - плохая привычка: у класса String есть метод c_str(), который выдаёт константный указатель на внутренний буфер, и если не надо этот буфер менять (как в вашем примере) - то лучше юзать именно этот метод. З.Ы. И да, по теме: exists - у меня работает, как надо, версия IDE 1.6.7