Преобразовать двоичный файл в char

string spiffs

Я читаю текстовый файл, сохраненный на моем устройстве ESP8266 (используя LittleFS).

while (myFile.available()) {
        Serial.write(myFile.read());
    }

Моя цель — сохранить содержимое файла (каждую строку) в массив String / char. myFile.read() возвращает двоичный файл, и я ищу быстрый и элегантный способ сделать это (как в Serial.write, который преобразует его в текст).

Парень

, 👍0

Обсуждение

Непонятно, что вы пытаетесь сделать. Двоичные и символы — это просто разные представления одних и тех же данных. Serial.write() просто отправляет данные как есть, а монитор Serial затем интерпретирует эти данные как ASCII. Но Arduino не заботится о том, что представляют собой данные. Для Arduino все это просто двоичные данные. Интерпретация символов предназначена только для нас, людей, и выполняется в последовательном мониторе, а не в Arduino. Итак, когда вы хотите поместить данные в массив символов, просто сделайте так: array[position] = myFile.read()., @chrisl

@chrisl - я пытаюсь извлечь текст. Когда я сделал, как вы объяснили... я получил только кучу цифр, @Guy . D

Вам нужно предоставить полный код, где вы получили только кучу цифр. Все дело в том, как вы пишете или печатаете его в Serial. Символ также может быть интерпретирован как число, поэтому, вероятно, вы просто неправильно выводите его в Serial., @chrisl

дело в том, что специально write не выполняет преобразование. print преобразует число в текстовое представление, разлагая его на цифры и сопоставляя каждую цифру с ascii.. поэтому из байта со значением 123 он печатает строку «123», состоящую из символов «1», «2», «3». . но write отправляет 123 как t, и Serial Monitor печатает символ с этим значением, то есть '{'., @Juraj


1 ответ


Лучший ответ:

2

myFile.read() возвращает один символ. Этот символ может быть представлен в виде числа (например, 65 для «A») или символа или чего угодно. Все просто число.

Буквы — это просто наше личное представление определенных чисел как людей. Вы можете думать об этом как о числах, представленных в базе 256, где каждому значению от 0 до 255 назначается уникальный символ.

Serial.write() просто дословно передает этот номер на компьютер, который затем сопоставляет его в последовательном мониторе с соответствующей буквой в таблице ASCII.

Благодаря объектно-ориентированному и полиморфному характеру API Arduino (см. Полиморфизм C++) разница между чтением из файла и чтением из серийного номера. Все они наследуют один и тот же класс Stream, предоставляющий вам одни и те же функции независимо от того, что вы читаете.

Таким образом, вы могли бы, подобно Serial, считывать каждый байт из файла по одному, пока не дойдете до символа(ов) конца строки (\n для файла Unix или \ r\n для файла Windows) и добавить каждый в конец строки (либо объект String, который осуждается , хотя и в меньшей степени на более способных микроконтроллерах, таких как ESP8266 и ESP32 или массив char).

В качестве альтернативы вы можете использовать одну из вспомогательных функций класса Stream, например readStringUntil(), которая считывает всю строку до (и отбрасывает) указанного завершающий символ и возвращает String.

Однако у обоих есть проблемы, когда дело доходит до построения массива всех результатов, особенно если вы заранее не знаете, сколько строк в файле, поскольку в C++ массивы имеют фиксированный размер.

Лучшее решение, если вы действительно делаете все это в ОЗУ (см. ниже), может состоять в том, чтобы сначала забыть о строках и просто прочитать весь файл в память. Как только он окажется в памяти, вы сможете прочитать весь блок данных, считая количество байтов \n (и добавить один, если он не заканчивается на \n). Это даст вам количество строк в файле.

Затем вы можете выделить массив указателей с тем же количеством записей, что и строк.

Оттуда вы можете использовать strtok() для данных, чтобы разделить их на фрагменты по байтам \n и назначить каждый фрагмент одному из указателей в вашем массиве. . Затем этот массив становится своего рода индексом данных.

Но возникает вопрос... зачем вообще хранить эти данные в оперативной памяти? У вас есть флэш-память, и доступ к ней довольно быстрый (не такой быстрый, как внутренняя флэш-память в традиционном MCU, но все же во много раз быстрее, чем, например, SD-карта). Если вашей целью является простота навигации по данным, возможно, вам следует подумать о лучших способах хранения ваших данных. В зависимости от того, что представляют собой эти данные, возможно, файловая структура на основе записей фиксированного размера с использованием struct для управления данными будет лучшим решением - тогда вы можете просто искать кратные размеру записи (или структуры), чтобы практически мгновенно переходить к разным записям в файле.

Если это текстовые данные, то, возможно, чтение файла и запись смещений в файле начала каждой строки в массиве (примечание: два прохода - один для подсчета строк для выделения массива и один для записи смещений в массив). array) аналогично индексации блока данных, описанной выше, было бы лучшим решением. Таким образом, вы сохраняете только 4 байта на запись в своем массиве, а не все данные. Поиск выполняется мгновенно (просто найдите смещение, хранящееся в массиве, для нужной строки), и вам не нужно хранить все данные в ОЗУ.

,