Как сделать WebClient.write() изображением, хранящимся в строке?

esp32 web

Мое приложение работает на ESP32-CAM. Он делает снимки и хранит их для ШПИОНОВ. Периодически SPIFFS проверяется и если изображения найдены: 1 - Изображение сохраняется на FTP-сервере 2 - Изображение передается в веб-сервис, который возвращает некоторую информацию об изображении 3 - Значения сохраняются в MySQL 4 - Изображение удаляется из SPIFFS

Чтобы прочитать изображение из SPIFFS, я использую следующий фрагмент кода:

String imageName   = file.name();  
imageBuffer = "";
while (file.available()){
   imageBuffer += char(file.read());
}

FTP-передача отлично работает со следующей командой:

ftp.WriteData((uint8_t*)imageBuffer.c_str(),imageBuffer.length());

Сервис, на который отправляется изображение для анализа, работает нормально, если я использую команду:

webClient.write(fb->buf,fb->len);

Но поскольку он не может быть использован в текущей реализации моего проекта, я пытаюсь работать с:

webClient.write((uint8_t*) imageBuffer.c_str(), imageBuffer.length());

Я не получаю никаких ошибок в ответ, но это просто не работает, и веб-сервис в пункте назначения ничего не возвращает.

Что я делаю не так?

, 👍1

Обсуждение

То, что вы делаете, - это рассматриваете двоичные данные как текст. Как только вы получите 0 байт, строка будет усечена., @Majenko

Ваш `WebClient.write () " выглядит нормально, но как вы оформляете эти необработанные данные? См. [Как работает загрузка файлов HTTP?](https://stackoverflow.com/questions/8659808)., @Edgar Bonet

Короткие знания о том, как обрабатывать такого рода данные. "обрамление необработанных данных"? Что это значит?, @Paulo Borges

@Majenko: Объект "String" не усекает первое значение NUL: он сохраняет все байты, которые вы нажимаете с помощью"+=", а метод "length ()" возвращает общее количество байтов, включая встроенные значения NUL., @Edgar Bonet

Краткий ответ: вы не можете хранить необработанные данные изображения в строке., @Majenko

"То, что вы делаете, - это обрабатываете двоичные данные как текст" в результате поиска в Интернете. Как это работало с FTP, я попробовал тот же вид или команду с WebClient, но не получилось. Честно говоря, я действительно не понимаю, что я делаю на этом двоичном уровне. Поиск в Интернете и попытка понять, что работает., @Paulo Borges

@EdgarBonet Я ожидал бы, что в итоге получится строка, в которой нет нулей, так как добавление НУЛЯ в конец строки не будет иметь никакого эффекта., @Majenko

“обрамление” - это материал, который вы помещаете вокруг данных. Смотрите ссылку, которую я предоставил. @Majenko: да, можно., @Edgar Bonet

Я хотел бы понять, почему он работает с FTP, но не с WebClient, @Paulo Borges

Мое плохое понимание говорит мне, что что-то связано с пробелами и нулями, но я не знаю, как это уладить., @Paulo Borges

@EdgarBonet Внутренне String::concat() использует strcpy(). Следовательно, он будет копировать все, что угодно, вплоть до первого НУЛЯ, заменяя любой конечный НУЛЬ, который уже есть., @Majenko

@Majenko: попробуй это! Я сделал., @Edgar Bonet

Я попробую это сделать. Спасибо, @Paulo Borges

@EdgarBonet, я бы предпочел не делать этого, спасибо. Я держусь *ну* подальше от Веревки и всего, что с ней связано. Никогда не используйте строку для *чего-либо*. Мало того, что это вообще плохая идея, вы просто не можете доверять тому, что она делает. И независимо от этого: хранение необработанных двоичных данных в строке вызывает проблемы., @Majenko


2 ответа


1

Не следует использовать строку для хранения двоичных данных.

Вместо этого выделите себе массив uint8_t нужного размера.

uint8_t *imageData;
size_t len = file.size();

imageData = alloca(len);
file.readBytes(imageData, len);

webClient.write(imageData, len);

С учетом сказанного, не зная, что делает остальная часть вашей программы, я могу только предположить, что вы просто взрываете необработанные данные на веб-сервере и надеетесь, что они застрянут. Это не то, как работает веб-передача данных. Вы должны правильно создать страницу загрузки в виде многосоставных данных mime-формы. Прочтите это для получения дополнительной информации

,

Привет, спасибо, с одной стороны, я отправляю его в библиотеку FTP и предполагаю, что он будет обрабатывать поток. Отправка в веб-службу осуществляется по протоколу HTTP, поэтому я не знаю,но когда я использую WebClient.write(fb->buf, fb - >>len); это работает, поэтому я предполагаю, что он обрабатывает около 24 тыс. байт изображения. Что ты предлагаешь мне делать? Спасибо, @Paulo Borges


1

Хорошо, я получил его работать следующим образом:

Больше не передавая двоичный файл, передавая имя файла, так что функция FTPPost будет делать свое собственное чтение файла на SPIFFS и будет публиковать в 256 байтах. Та же стратегия работает с HTTP post на веб-сервис.

  File picFile = SPIFFS.open(fileName,FILE_READ);
  const size_t bufferSize = 256;
  uint8_t buffer[bufferSize];
  while (picFile.available()) {
    size_t n = picFile.readBytes((char*) buffer, bufferSize);
    if (n != 0) {
      ftp.WriteData(buffer, n);
    } else {
      Serial.println(F("Buffer was empty"));
      break;
    }
  }
  picFile.close();
,