Code Assistance - stream multiple data files from SD to web user fails

StephenGinHampshire
Posts: 1
Joined: Fri Sep 16, 2022 7:16 pm

Code Assistance - stream multiple data files from SD to web user fails

Postby StephenGinHampshire » Thu Dec 01, 2022 9:23 pm

I am writing an ESP32 subroutine (Windows 10/Visual Studio/VMicro) where I wish to copy (or stream) all the files in the root drive of an SD Card attached to a ESP32 WROOM DA.
The code is initiated by selecting a function on the driven webpage, this executes the subroutine "Save_Files", the code uses the openNextFile() subroutine to select and then open a file on the SD drive and then uses the combination of the two lines :
server.sendHeader("Content-Disposition", "attachment; filename=" + filename); // defines the filename of target file
if (server.streamFile(datafile, contentType) != datafile.size()) {
to stream the file to the PC where the webpage is displayed. The code then loops through the files in the root directory until all the files have been streamed.
Unfortunately although the first file streams correctly subsequent files are not streamed correctly, the comparison between the number of bytes sent (server.streamFile(datafile, contentType ) and the number of bytes in the source file (datafile.size().
If I put an arbitary delay between the server.sendHeader line and the server.streamFile lines more data is sent.
Here is a copy of the serial monitor whilst the programme is running and the download files selected:
Opening System Volume Information
44628 Opening 20221126.csv
44629 Target File 20221126.csv
44721 File Sent Correctly
44724 Opening 20221127.csv
44725 Target File 20221127.csv
47390 Sent less data than expected!
47390 Bytes Sent: 0
47390 File Size : 1208131
47393 Opening 20221128.csv
47394 Target File 20221128.csv
50057 Sent less data than expected!
50057 Bytes Sent: 0
50057 File Size : 1209461
50060 Opening 20221129.csv
50061 Target File 20221129.csv
52696 Sent less data than expected!
52697 Bytes Sent: 0
52697 File Size : 1197281
52700 Opening 20221130.csv
52701 Target File 20221130.csv
54756 Sent less data than expected!
54756 Bytes Sent: 0
54756 File Size : 933381
54759 Opening 20221201.csv
54760 Target File 20221201.csv
54894 Sent less data than expected!
54894 Bytes Sent: 0
54894 File Size : 59792
54897 All files saved from root directory
55910 10. Record Written

The server.streamFile for files 1+ has a byte count of 0 (zero)!
Can anyone suggest the reason and how to correct it, is there a query I could use to "wait" for the completion of the streaming before I loop to get the next file? Any help would be appreciated.


<code>
void Save_Files() { // Save all files in the root directory of the SD Card to PC
String filename;
File root = SD.open("/"); // Open the root directory
bool active = true; // used to maintain loop while there are files to save
File entry; // root directory
File datafile; // "next" file
String contentType; // type of content required
while (active) { // loop until no files left
entry = root.openNextFile(); // get the next file from the directory
if (entry) { // if there is a file
active = true; // ensure loop is active while there are files
filename = entry.name(); // get the file name
console.print(millis(), DEC); console.print("\t\tOpening "); console.println(filename); // print the file name
datafile = SD.open("/" + filename, FILE_READ); // Now open the data file
if (datafile) { // if there is a file
if (datafile.available()) { // If data is available and present
contentType = "application/octet-stream"; // type of content required
console.print(millis(), DEC); console.print("\t\tTarget File "); console.println(filename); // print the file name
server.sendHeader("Content-Disposition", "attachment; filename=" + filename); // defines the filename
if (server.streamFile(datafile, contentType) != datafile.size()) {
console.print(millis(), DEC); console.println("\t\tSent less data than expected!");
unsigned long bytes_written = server.streamFile(datafile, contentType);
console.print(millis(), DEC); console.print("\t\tBytes Sent: "); console.println(bytes_written, DEC);
console.print(millis(), DEC); console.print("\t\tFile Size : "); console.println(datafile.size(), DEC);
}
else {
console.print(millis(), DEC); console.print("\t\tFile Sent Correctly");
}
}
}
datafile.close(); // close the file:
datafile.flush();
}
else { // there are no more files
root.close(); // so close the directory
console.print(millis(), DEC);
console.println("\t\tAll files saved from root directory");
active = false; // and exit the while loop
}
}
webpage = "";
}

lbernstone
Posts: 826
Joined: Mon Jul 22, 2019 3:20 pm

Re: Code Assistance - stream multiple data files from SD to web user fails

Postby lbernstone » Fri Dec 02, 2022 9:22 pm

I think your problem here is with http rather than the coding. You can only download one file at a time through a web browser. If you want to pull a group of files, you need to either zip them up into a single file, or else write some javascript to break them into separate files on the client end. There may also be some way to do this with multipart forms if you want to just present the content in a browser window. As it is, what you are probably seeing is that after sending a single file, the transaction is completed (a double CR), so the client refuses to take the additional data, and you get 0 bytes streamed.

Who is online

Users browsing this forum: No registered users and 89 guests