SD / SdFs / FsFile
SdFs and FsFile are class objects for interacting with the SD card reader. SdFs is necessary for initializing the SD card and can be used for listing files and directories, showing the file system and other functions. FsFile is a class object for interacting with a specific file or directory and can be used for reading and writing data. The two classes have some overlapping functionality (using either class works), but you must run SdFs' begin before using the SD card. For an example using these classes to interact with files on the SD card, see the SD Card Example.
To use these classes, first add the following line to the top of your program:
#include "SdFat.h"
SdFs
SdFs can be instantiated as a global object so it can be accessed by any function, or it can be placed inside a function that will contain all the interactions with the SD card. This is instantiated with:
SdFs sd;
SdFS Class Functions
begin
bool begin(void);
Initializes the SD card and returns true if successful, and otherwise false.
Example
SdFs sd;
if (!sd.begin()) {
Serial.println("Error initializing SD Card");
return;
}
chdir
bool chdir(const char* path);
Change the current directory to the argument path.
Example
SdFs sd;
sd.begin();
sd.ls(&Serial);
bool res = sd.chdir("someDirectory/");
Serial.printf("chdir returned %s\n", res? "true": "false");
sd.ls(&Serial);
end
void end(void);
End access to the SD card.
exists
bool exists(const char* path);
Returns true if the given path exists, otherwise false.
Example
SdFs sd;
sd.begin();
const char filename[] = "Data.dat";
if (sd.exists(filename)) {
FsFile file = sd.open(filename);
...
}
fatType
uint8_t fatType(void);
Returns the type of FAT filesystem. FAT32 returns 32, FAT12 returns 12, etc, and exFAT returns 64. Unknown type returns 0.
Example
SdFs sd;
sd.begin();
uint8_t fatType = sd.fatType();
ls
bool ls(print_t* pr);
bool ls(print_t* pr, uint8_t flags);
Prints directory contents to a Print stream (like Serial). The flags argument can be left off, but valid flag values are:
LS_DATE-- print modification dateLS_SIZE-- print file sizeLS_R-- recursively list subdirectories
Example
SdFs sd;
sd.begin();
sd.ls(&Serial, LS_SIZE);
mkdir
bool mkdir(const char* path);
bool mkdir(const char* path, bool pFlag = true);
Create a new directory at the location specified by path. Takes an optional Boolean argument pFlag to create parent sub-directories automatically if necessary (default is true). Returns true for success and false for failure.
Example
SdFs sd;
sd.begin();
bool status = sd.mkdir("NewDirectory");
if (status) {
//directory created successfully
...
}
printFatType
void printFatType(print_t* pr);
Takes a pointer to an object such as Serial that can print output. Prints the filesystem type (exFAT, FAT32, etc).
Example
SdFs sd;
if (!sd.begin()) {
Serial.println("Error initializing SD Card");
return;
}
sd.printFatType(&Serial); // Outputs 'FAT32' for example
printSdError
void printSdError(print_t* pr);
Takes an argument of a pointer to an object such as Serial that can print an output. Prints the SD card error info.
Example
SdFs sd;
if (!sd.begin()) {
Serial.println("Error with SD initialization");
sd.printSdError(&Serial);
return;
}
When no card is present, the example would output
Error with SD initialization
SD error: SD_CARD_ERROR_ACMD41 = 0x17,0x0
remove
bool remove(const char* path);
Remove (delete) a file at the location path from the filesystem. Returns true if successful, otherwise false.
rename
bool rename(const char* oldPath, const char* newPath);
Renames a file from oldPath to newPath and returns true if successful, otherwise false.
rmdir
bool rmdir(const char* path);
Removes an empty directory (directory must be empty). Returns true if successful, otherwise false.
open
FsFile open(const char* path);
FsFile open(const char* path, oflag_t oflag = O_RDONLY);
Opens a file and returns a FsFile object. By default, opens the file read-only, but by passing oflag to the open command, it can be opened with the following properties:
O_RDONLY-- Read OnlyO_WRONLY-- Write OnlyO_RDWR-- Read and WriteO_APPEND-- Append ModeO_CREAT-- Create file if it does not already existO_EXCL-- Fail if file already exists
These properties can be combined with the "|" operator, as shown below:
Example
SdFs sd;
sd.begin();
FsFile file = sd.open("OldFile.txt", O_CREAT | O_WRONLY);
FsFile
A FsFile class can be instantiated with
FsFile file;
This class object can be associated with a file or directory either via SdFs' open function:
SdFs sd;
sd.begin();
FsFile file = sd.open("Data.txt");
or directly using the FsFile's open function:
SdFs sd;
sd.begin();
FsFile file;
file.open("Data.txt");
Either approach works the same. Once the FsFile object is associated with a file or directory, you can read and write to the file and perform other actions using the FsFile functions. In addition to the class functions listed below, FsFile inherits from the Stream class, so all Stream methods (for example readString and find) are available. For a list of Stream methods, see the Stream documentation.
FsFile Class Functions
- close
- exists
- fileSize
- flush
- getName
- isDir
- isFile
- isOpen
- isWritable
- ls
- open
- openNextFile
- read
- remove
- rename
- rewindDirectory
- sync
- write
close
bool close(void);
Closes the file and writes cached data to the card.
exists
bool exists(const char* path);
Checks for the existence of a file named path in the current directory and returns true if the file is present, otherwise false. Will not work unless the active FsFile object refers to a directory.
Example
FsFile file;
file.open("/"); // file must be opened to a directory for exists function
if (file.exists("data.txt")) {
Serial.println("data.txt exists in /.");
}
fileSize
uint64_t fileSize(void);
Returns total file size in bytes. Returns 0 if the file is a directory.
flush
void flush(void);
Ensures that any bytes written to the file are saved to the SD card (and not cached). Run this or close before ejecting the SD card to make sure all file writes have completed.
getName
size_t getName(char* name, size_t len);
Retrieves the file’s name into name buffer (max len bytes).
Example
char tempName[50];
FsFile root;
FsFile file;
root.open("/");
root.rewindDirectory();
while(file = root.openNextFile()){
file.getName(tempName,sizeof(tempName));
Serial.printf("File name is: %s\n", tempName);
}
isDir
bool isDir(void);
Returns true if the opened object is a directory.
isFile
bool isFile(void);
Returns true if the opened object is a file.
isOpen
bool isOpen(void);
Returns true if the object has opened a file or directory.
isWritable
bool isWritable(void);
Returns true if the opened file is writable.
ls
bool ls(print_t* pr);
Prints directory contents to a Print stream (like Serial).
Example
FsFile dir = sd.open("/");
dir.ls(&Serial);
dir.close();
open
bool open(const char* path, oflag_t oflag = O_RDONLY);
Opens a file or directory at the given path with the specified flags. See SdFS's open function for oflag options.
Returns true on success.
Example
FsFile file;
if (file.open("/data.txt", O_RDONLY)) {
Serial.println("File opened");
file.close();
}
openNextFile
FsFile openNextFile(oflag_t oflag = O_RDONLY);
Opens the next file or folder in a directory. The function should be called from an open directory. Additionally, to start at first item in the directory, call rewindDirectory before calling this function in a loop, as shown in the example below.
Example
FsFile dir = sd.open("/logs");
char tempName[50];
dir.rewindDirectory();
FsFile file;
while (file = dir.openNextFile()) {
file.getName(tempName, sizeof(tempName));
Serial.printf("File name is: %s\n", tempName);
file.close();
}
dir.close();
read
int read(void* buf, size_t count);
Reads up to count bytes into buf, returns number of bytes read or -1 on error.
Example
FsFile file;
file.open("/data.txt", O_RDWR);
uint8_t buffer[64];
int bytes = file.read(buffer, sizeof(buffer));
if (bytes > 0) Serial.write(buffer, bytes);
remove
bool remove();
Deletes the currently open file. Returns true if successful.
rename
bool rename(const char* newPath);
Renames the file or directory to newPath.
rewindDirectory
void rewindDirectory(void);
If the object is an open directory, sets internal referencing to the top of the directory. This function should be called before iterating over openNextFile or else the iteration may not start at the top of the directory. See openNextFile for an example.
sync
bool sync();
Flushes buffered writes and updates directory entry metadata.
write
size_t write(const void* buf, size_t count);
Tried to writes count bytes of data from buf into file, returns actual number of bytes written.
Example
FsFile file;
file.open("/data.txt", O_RDWR);
uint8_t buffer[10] = {0,1,2,3,4,5,6,7,8,9};
int bytes = file.write(buffer, sizeof(buffer));
Serial.printf("Wrote %u bytes to file.\n", bytes);