1
+ /*
2
+ Listfiles Enhanced
3
+
4
+ This example shows how to list files in SDcard in the following way:
5
+ 1) collect all directories
6
+ 2) build full path of directories and keep in mind
7
+ 3) then print all files with the help of the directorie pathes
8
+
9
+ The circuit:
10
+ SD card attached to SPI bus as follows:
11
+ ** MOSI - pin 11
12
+ ** MISO - pin 12
13
+ ** CLK - pin 13
14
+ ** CS - pin 4
15
+
16
+ created:
17
+
18
+ 18. Nov 2024
19
+ by Frank Häfele
20
+
21
+ This example code is in the public domain.
22
+
23
+ */
24
+ #include < SPI.h>
25
+ #include < SD.h>
26
+ #include < vector>
27
+
28
+ #define SD_CS_PIN 2
29
+
30
+
31
+ void dir (String path) {
32
+ std::vector<String> directories;
33
+ collectDirectories (path, directories);
34
+ for (auto directory:directories) {
35
+ printDirectoryName (directory.c_str (), 1 );
36
+ File fs = SD.open (directory);
37
+ printFilesInDirectory (fs);
38
+ Serial.println (" \n ===============" );
39
+ fs.close ();
40
+ }
41
+ }
42
+
43
+ void setup () {
44
+ // Open serial communications and wait for port to open:
45
+ Serial.begin (115200 );
46
+
47
+ Serial.print (" \n\n ==== List Directory ====\n\n " );
48
+ listDirectory ();
49
+
50
+ Serial.println (" done!" );
51
+ }
52
+
53
+ void loop () {
54
+ // nothing happens after setup finishes.
55
+ }
56
+
57
+ void listDirectory () {
58
+ Serial.print (" \n\n Initializing SD card..." );
59
+ if (!SD.begin (SD_CS_PIN)) {
60
+ Serial.println (" initialization failed!" );
61
+ return ;
62
+ }
63
+ Serial.print (" initialization successful.\n " );
64
+ Serial.print (" List Files:\n " );
65
+ dir (" /" );
66
+ }
67
+
68
+
69
+ void printDirectoryName (const char * name, uint8_t level) {
70
+ for (uint8_t i = 0 ; i < level; ++i) {
71
+ Serial.print (" " );
72
+ }
73
+ Serial.println (name);
74
+ }
75
+
76
+
77
+
78
+ // helper function: combine path
79
+ String joinPath (const String &base, const String &name) {
80
+ if (base.endsWith (" /" )) {
81
+ return base + name;
82
+ }
83
+ return base + " /" + name;
84
+ }
85
+
86
+ // recusive function to collect directory names
87
+ void collectDirectories (const String &dirname, std::vector<String> &directories) {
88
+ File root = SD.open (dirname);
89
+ if (!root || !root.isDirectory ()) {
90
+ Serial.printf (" Error: Verzeichnis %s konnte nicht geöffnet werden\n " , dirname.c_str ());
91
+ return ;
92
+ }
93
+ directories.push_back (dirname); // Verzeichnis speichern
94
+
95
+ File file = root.openNextFile ();
96
+ while (file) {
97
+ if (file.isDirectory ()) {
98
+ String fullPath = joinPath (dirname, file.name ()); // Vollständigen Pfad erstellen
99
+ collectDirectories (fullPath, directories); // Rekursiver Aufruf
100
+ }
101
+ file = root.openNextFile ();
102
+ }
103
+ root.close ();
104
+ }
105
+
106
+ // print filenames
107
+ void printFileName (File file) {
108
+ Serial.print (" \t " );
109
+ Serial.printf (" %30s" , file.name ());
110
+ // files have sizes, directories do not
111
+ Serial.print (" - " );
112
+ Serial.print (file.size (), DEC);
113
+ time_t cr = file.getCreationTime ();
114
+ time_t lw = file.getLastWrite ();
115
+ struct tm * tmstruct = localtime (&cr);
116
+ Serial.printf (" \t CREATION: %d-%02d-%02d %02d:%02d:%02d" , (tmstruct->tm_year ) + 1900 , (tmstruct->tm_mon ) + 1 , tmstruct->tm_mday , tmstruct->tm_hour , tmstruct->tm_min , tmstruct->tm_sec );
117
+ tmstruct = localtime (&lw);
118
+ Serial.printf (" \t LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n " , (tmstruct->tm_year ) + 1900 , (tmstruct->tm_mon ) + 1 , tmstruct->tm_mday , tmstruct->tm_hour , tmstruct->tm_min , tmstruct->tm_sec );
119
+ }
120
+
121
+
122
+ // print files in directories
123
+ void printFilesInDirectory (File dir) {
124
+ while (true ) {
125
+ auto file = dir.openNextFile ();
126
+ if (!file) {
127
+ // no more files
128
+ break ;
129
+ }
130
+ if (file.isDirectory ()) {
131
+ continue ;
132
+ }
133
+ else {
134
+ printFileName (file);
135
+ }
136
+ }
137
+ }
0 commit comments