ESP32 WebServer Library – streamFile()

Home / References / ESP32 Library / WebServer Library

Description

The streamFile() method in the ESP32 WebServer Library allows you to stream a file directly from a filesystem (like SPIFFS or SD) to a connected client over HTTP. This method is ideal for serving large files, such as HTML pages, images, or other resources, without loading them entirely into memory, making it memory-efficient and practical for resource-constrained ESP32 projects.


Syntax and Usage

The streamFile() method has a single, flexible syntax that supports streaming files with a specified content type and optional HTTP status code. Here’s how to use it:

Basic Usage with Default Status Code (200 OK):

server.streamFile(file, contentType);

Streams a file with the specified content type and defaults to HTTP status code 200.

Usage with Custom Status Code:

server.streamFile(file, contentType, code);

Allows you to specify a custom HTTP status code (e.g., 404 for not found) along with the content type.

For practical applications and examples of this method, please consult the “Example Code” section on this page. This section provides comprehensive guidance to help you better understand and apply the method effectively.


Argument(s)

  • file: A reference to the file object (e.g., from FS like SPIFFS or SD) that you want to stream. This is typically a File object opened in read mode.
  • contentType: A string specifying the MIME type of the file (e.g., "text/html" for HTML files, "image/jpeg" for images). This informs the client how to interpret the file.
  • code (optional): An integer representing the HTTP status code (e.g., 200 for OK, 404 for Not Found). If omitted, it defaults to 200.

Return Value

The streamFile() method returns a size_t value representing the number of bytes successfully streamed to the client. This can be useful for verifying that the entire file was sent or for debugging purposes.


Example Codes

Below are practical examples demonstrating the different ways to use the streamFile() method. Each example is designed to help you integrate this method into your ESP32 projects effectively.

Example 1: Streaming an HTML File with Default Status Code

This code demonstrates how to use the ESP32 WebServer Library’s streamFile() method to serve an HTML file stored in SPIFFS to a client when they access the root URL (“/”). It allows the ESP32 to efficiently send large files without loading the entire file into memory.

To use this code, replace “your-SSID” and “your-PASSWORD” with your Wi-Fi credentials. Note: You must upload an “index.html” file to the ESP32’s SPIFFS for this code to function correctly. Without this file, the server will return a 404 error. After uploading the code and the “index.html” file to your ESP32, open a web browser and navigate to the ESP32’s IP address to view the HTML content.

ESP32 LittleFS File Upload

To ensure the following example code runs properly, you need to upload necessary files to the LittleFS File System of your ESP32 microcontroller. If you are unsure how to do this, please check out our LittleFS reference for detailed instructions. You can access the reference directly by clicking on the following URL.

ESP32 LittleFS Library

/*
 * Author: Avant Maker
 * Date: March 17, 2025
 * Version: 1.0
 * License: MIT 
 * 
 * Description: 
 * This example demonstrates how to use ESP32 WebServer Library's 
 * streamFile() to serve an HTML file stored in SPIFFS to a client
 * when they access the root URL ("/"). It allows the ESP32 to
 * efficiently send large files without loading the entire file
 * into memory.
 *
 * Code Source:
 * This example code is sourced from the Comprehensive Guide
 * to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
 * For additional code examples and in-depth documentation related to
 * the ESP32 Arduino Core Library, please visit:
 *
 * https://avantmaker.com/home/all-about-esp32-arduino-core-library/
 *
 * AvantMaker.com, your premier destination for all things
 * DIY, AI, IoT, Smart Home, and STEM projects. We are dedicated
 * to empowering makers, learners, and enthusiasts with
 * the resources they need to bring their innovative ideas to life.
 */

#include <WiFi.h>
#include <WebServer.h>
#include <FS.h>
#include <LittleFS.h>

// Network credentials
const char* ssid = "your-SSID";          // Replace with your Wi-Fi SSID
const char* password = "your-PASSWORD";  // Replace with your Wi-Fi password

// Web server port number
WebServer server(80);

// File paths
const char* indexPath = "/index.html";

// MIME types for common file extensions
const char* getContentType(String filename) {
  if (filename.endsWith(".html")) return "text/html";
  else if (filename.endsWith(".css")) return "text/css";
  else if (filename.endsWith(".js")) return "application/javascript";
  else if (filename.endsWith(".ico")) return "image/x-icon";
  else if (filename.endsWith(".json")) return "application/json";
  else if (filename.endsWith(".png")) return "image/png";
  else if (filename.endsWith(".jpg")) return "image/jpeg";
  else if (filename.endsWith(".gif")) return "image/gif";
  else if (filename.endsWith(".svg")) return "image/svg+xml";
  return "text/plain";
}

void setup() {
  // Initialize serial communication
  Serial.begin(115200);
  
  // Initialize LittleFS
  if (!LittleFS.begin()) {
    Serial.println("LittleFS mount failed");
    return;
  }
  Serial.println("LittleFS mounted successfully");
  
  // List files in LittleFS for debugging
  listFiles();
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  // Define server routes
  server.on("/", HTTP_GET, handleRoot);
  
  // Define handler for any file request
  server.onNotFound(handleNotFound);
  
  // Start server
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  // Handle client requests
  server.handleClient();
  delay(10);
}

// Handler for root page
void handleRoot() {
  serveFile(indexPath);
}

// Handle file requests using streamFile method
void serveFile(const char* path) {
  Serial.print("Requested file: ");
  Serial.println(path);
  
  if (LittleFS.exists(path)) {
    File file = LittleFS.open(path, "r");
    if (file) {
      // Get MIME type based on file extension
      String contentType = getContentType(String(path));
      
      // Stream the file to the client
      server.streamFile(file, contentType);
      
      // Close the file when done
      file.close();
      Serial.println("File served successfully");
    } else {
      Serial.println("Failed to open file for reading");
      server.send(500, "text/plain", "Internal Server Error");
    }
  } else {
    Serial.println("File not found");
    server.send(404, "text/plain", "File Not Found");
  }
}

// Handle requests for files not found
void handleNotFound() {
  // Check if the requested URI is a file
  String path = server.uri();
  
  // If the path doesn't start with a slash, add one
  if (!path.startsWith("/")) {
    path = "/" + path;
  }
  
  // Try to serve the file
  if (LittleFS.exists(path)) {
    serveFile(path.c_str());
  } else {
    // If file doesn't exist, return 404
    String message = "File Not Found\n\n";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET) ? "GET" : "POST";
    message += "\nArguments: ";
    message += server.args();
    message += "\n";
    
    for (uint8_t i = 0; i < server.args(); i++) {
      message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
    }
    
    server.send(404, "text/plain", message);
  }
}

// List all files in LittleFS (for debugging)
void listFiles() {
  Serial.println("Files in LittleFS:");
  
  File root = LittleFS.open("/", "r");
  if (!root) {
    Serial.println("Failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println("Not a directory");
    return;
  }
  
  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("DIR: ");
    } else {
      Serial.print("FILE: ");
      Serial.print(file.name());
      Serial.print(" (");
      Serial.print(file.size());
      Serial.println(" bytes)");
    }
    file = root.openNextFile();
  }
  Serial.println("---------------------");
}

Example 2: Streaming an Image with Custom Status Code

This code demonstrates how to use the ESP32 WebServer Library’s streamFile() method to serve a JPEG image from SPIFFS with a custom HTTP status code. It also handles the case where the image file is not found, sending a 404 status code.

To use this code, replace “your-SSID” and “your-PASSWORD” with your Wi-Fi credentials. Note: You must upload a “photo.jpg” image file to the ESP32’s SPIFFS for this code to function correctly. Without this file, the server will return a 404 error. After uploading the code and the image file to your ESP32, open a web browser and navigate to the ESP32’s IP address followed by “/image” (e.g., 192.168.1.100/image) to view the image.

ESP32-WebFS: Simplifying SPIFFS File Management for Your ESP32 Projects

If you are looking for a tool or need guidance to upload and manage files in the SPIFFS (SPI Flash File System) of your ESP32 microcontroller, please check out our GitHub project, ESP32-WebFS , which simplifies SPIFFS file management for your ESP32 projects. It also serves as a great reference project that you can integrate into your own projects requiring ESP32 SPIFFS management.

ESP32-WebFS can turn your ESP32 microcontroller into a web server that provides a web-based interface to manage the SPIFFS on your ESP32. It enables you to upload, download, delete, and view files stored on your ESP32, making it easy to interact with your ESP32’s file system wirelessly.

For downloads and instructions on how to use this tool, please visit the ESP32-WebFS GitHub repository.

/*
 * Author: Avant Maker
 * Date: March 17, 2025
 * Version: 1.0
 * License: MIT 
 * 
 * Description: 
 * This example demonstrates how to use ESP32 WebServer Library's 
 * streamFile() to stream a JPEG image from SPIFFS with a custom
 * HTTP status code. It checks if the file exists and sends a
 * 404 status if it doesn't.
 *
 * Code Source:
 * This example code is sourced from the Comprehensive Guide
 * to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
 * For additional code examples and in-depth documentation related to
 * the ESP32 Arduino Core Library, please visit:
 *
 * https://avantmaker.com/home/all-about-esp32-arduino-core-library/
 *
 * AvantMaker.com, your premier destination for all things
 * DIY, AI, IoT, Smart Home, and STEM projects. We are dedicated
 * to empowering makers, learners, and enthusiasts with
 * the resources they need to bring their innovative ideas to life.
 */

#include <WiFi.h>
#include <WebServer.h>
#include <FS.h>
#include <SPIFFS.h>

const char* ssid = "your-SSID";          // Replace with your Wi-Fi SSID
const char* password = "your-PASSWORD";  // Replace with your Wi-Fi password

WebServer server(80);

void setup() {
    Serial.begin(115200);
    SPIFFS.begin();
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("Connected: ");
    Serial.println(WiFi.localIP());

    server.on("/image", []() {
        File file = SPIFFS.open("/photo.jpg", "r");
        if (file) {
            size_t sent = server.streamFile(file, "image/jpeg", 200);
            Serial.print("Bytes sent: ");
            Serial.println(sent);
            file.close();
        } else {
            server.streamFile(file, "text/plain", 404); // File object is invalid, but status is set
            server.send(404, "text/plain", "Image not found");
        }
    });
    server.begin();
}

void loop() {
    server.handleClient();
}
error: Content is protected !!