Как читать бинарные файлы?

fixMix
Offline
Зарегистрирован: 26.06.2019

Создал веб сервер на ESP32 и заметил, что с помощью

File page = SD.open(server.uri(), FILE_READ);
      while (page.available() > 0) {
        page_a = page_a + page.read();
      }
      page.close();

картинки читаются, но не правильно. Просматривал содержимое через NotePad++. В оригинале много строк и разных символов, а в принятом через браузер, пару символов, остальное заполненно NULL. Что делать?

b707
Offline
Зарегистрирован: 26.05.2017

как описана переменная page_a

fixMix
Offline
Зарегистрирован: 26.06.2019

String

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, а чего Вы хотите? String - для строк, а не для бинарных данных.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

fixMix пишет:

Создал веб сервер на ESP32 и заметил, что с помощью

File page = SD.open(server.uri(), FILE_READ);
      while (page.available() > 0) {
        page_a = page_a + page.read();
      }
      page.close();

картинки читаются, но не правильно. Просматривал содержимое через NotePad++. В оригинале много строк и разных символов, а в принятом через браузер, пару символов, остальное заполненно NULL. Что делать?

Зачем читать в промежуточную переменную, если можно выплёвывать сразу в поток? Как думаете - ютюб так же делает: запросили у него видос размером гигабайт 100 на диске - он его в переменную вычитывает, и только потом отдаёт?

В вашем случае: запросили файл у сервера - отдавайте прямо из файла в выходной поток, всё.

fixMix
Offline
Зарегистрирован: 26.06.2019
File page = SD.open(server.uri(), FILE_READ);
      while (page.available() > 0) {
server.send(200, "text/html", page.read());
}
File.close();

Не работает

fixMix
Offline
Зарегистрирован: 26.06.2019
Весь код, если что
#include <SPI.h>
#include <SD.h>
#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "WebServer";
const char* password = "00000000";

int led = 15;

WebServer server(80);



void test() {
  Serial.println("Somebody open: " + server.uri());
  String page_a;
  digitalWrite(led, HIGH);
  if (SD.exists(server.uri())) {
    if (server.uri() == "/") {
      File page = SD.open("/index.html", FILE_READ);
      while (page.available() > 0) {
        page_a = page_a + char(page.read());
      }
      page.close();
      server.send(200, "text/html", page_a);
    }
    else {
      File page = SD.open(server.uri(), FILE_READ);
      while (page.available() > 0) {
        page_a = page_a + page.read();
      }
      page.close();
      char filename[100];
      (server.uri()).toCharArray(filename, 100);
      
      String type;
      if (strstr(filename, ".htm") != 0){
        type = "text/html";
        }

      else if (strstr(filename, ".css") != 0){
        type = "text/css";
        }

      else if (strstr(filename, ".png") != 0){
        type = "image/png";
      }

      else if (strstr(filename, ".jpg") != 0){
        type = "image/jpeg";
      }

      else if (strstr(filename, ".gif") != 0){
        type = "image/gif";
      }

      else if (strstr(filename, ".3gp") != 0){
        type = "video/mpeg";
      }

      else if (strstr(filename, ".pdf") != 0){
        type = "application/pdf";
      }

      else if (strstr(filename, ".js") != 0){
        type = "application/x-javascript";
      }

      else if (strstr(filename, ".xml") != 0){
        type = "application/xml";
      }

      else {
        type = "text";
      }

      server.send(200, type, page_a);
    }
  }
  else {
    File page = SD.open("/404.html", FILE_READ);
    while (page.available() > 0) {
      page_a = page_a + char(page.read());
    }
    page.close();
    server.send(200, "text/html", page_a);
  }
  digitalWrite(led, LOW);
}

void setup() {
  Serial.begin(115200);
  pinMode(led, OUTPUT);
  if (!SD.begin()) {
    Serial.println("Card Mount Failed");
    while(1){
      digitalWrite(led, HIGH);
      delay(300);
      digitalWrite(led, LOW);
      delay(300);
    }
  }


  Serial.println("Setting AP (Access Point)...");
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  server.begin();

  server.onNotFound(test);
  server.begin();
}

void loop() {
  server.handleClient();
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А допустимы ли в HTML бинарные данные? Законно ли это вообще?

b707
Offline
Зарегистрирован: 26.05.2017

fixMix пишет:

File page = SD.open(server.uri(), FILE_READ);
      while (page.available() > 0) {
server.send(200, "text/html", page.read());
}
File.close();

Не работает

если не ошибаюсь, этим кодом вы КАЖДЫЙ БАЙТ, прочитанный из файла - отправляете в сеть отдельным ответом. Не удивительно, что не работает....

fixMix
Offline
Зарегистрирован: 26.06.2019

Я знаю, я и не собирался.

b707
Offline
Зарегистрирован: 26.05.2017

fixMix пишет:

Я знаю, я и не собирался.

это кому?

Когда отвечаете - нажимайте кнопку "цитировать", а то не всегда понятно, к чему относится ответ

fixMix
Offline
Зарегистрирован: 26.06.2019

b707 пишет:

fixMix пишет:

Я знаю, я и не собирался.

это кому?

Когда отвечаете - нажимайте кнопку "цитировать", а то не всегда понятно, к чему относится ответ

Понял. Я имел ввиду, что я и не собирался это компилить.

b707
Offline
Зарегистрирован: 26.05.2017

fixMix пишет:

 Я имел ввиду, что я и не собирался это компилить.

Тогда зачем в форум выкладывали? И откуда узнали, что оно "не работает"?

Это троллинг7

fixMix
Offline
Зарегистрирован: 26.06.2019

b707 пишет:

fixMix пишет:

 Я имел ввиду, что я и не собирался это компилить.

Тогда зачем в форум выкладывали? И откуда узнали, что оно "не работает"?

Это троллинг7

Ну ошибся я. Хотел написать: Так что-ли? Это не работает.

b707
Offline
Зарегистрирован: 26.05.2017

fixMix пишет:

 Хотел написать: Так что-ли? Это не работает.

слушайте, да откуда вы узнали, что это не работает? У вас же свои знания на нуле

Нафига мы тут распинаемся, если вы просто взглянули на код и уже знаете, что работать не будет? Может вам стоит самому свою проблему решить в таком случае?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

У класса WebServer для ESP32 есть метод:

template<typename T>
  size_t streamFile(T &file, const String& contentType) {
    _streamFileCore(file.size(), file.name(), contentType);
    return _currentClient.write(file);
  }

Вот тут можно почитать, как юзать (какой-то issue, не вникал): https://github.com/esp8266/Arduino/issues/3966

fixMix
Offline
Зарегистрирован: 26.06.2019

Спасибо, попробую