### Install TinyFTPClient via Git Source: https://github.com/exocet22/tinyftpclient/blob/master/README.md Use this command to clone the library directly into your Arduino libraries folder. ```sh cd ~/Documents/Arduino/libraries/ git clone https://github.com/exocet22/TinyFTPClient TinyFTPClient ``` -------------------------------- ### Get Last Modified Time of Remote File Source: https://context7.com/exocet22/tinyftpclient/llms.txt Retrieves the last modification timestamp of a remote file using the MDTM command. The timestamp is written into the provided buffer. ```cpp char timestamp[32] = ""; if (ftp_client.get_last_modified_time("report.csv", timestamp)) { // timestamp format: "20240315143022" Serial.printf("Last modified: %s\n", timestamp); // Expected output: Last modified: 20240315143022 } else { Serial.println("MDTM failed"); } ``` -------------------------------- ### Instantiate FTPClient with Default Timeout Source: https://context7.com/exocet22/tinyftpclient/llms.txt Instantiates the FTP client using default TCP clients and the default 20-second timeout. ```cpp #include #include #include WiFiClient tcp_client; WiFiClient passive_tcp_client; // Default 20-second timeout FTPClient ftp_client(&tcp_client, &passive_tcp_client); ``` -------------------------------- ### Constructor Source: https://context7.com/exocet22/tinyftpclient/llms.txt Instantiate the FTP client with two TCP connections and an optional timeout. Two separate Client instances are required: one for the FTP control channel and one for the passive data channel. The default timeout is 20,000 ms. ```APIDOC ## Constructor **`FTPClient(Client* p_client, Client* p_passive_client, uint16_t timeout)`** — instantiate the FTP client with two TCP connections and an optional timeout. Two separate `Client` instances are required: one for the FTP control channel and one for the passive data channel. The default timeout is 20,000 ms. After construction, credentials and server address are provided at connection time via `open()`. ```cpp #include #include #include WiFiClient tcp_client; WiFiClient passive_tcp_client; // Default 20-second timeout FTPClient ftp_client(&tcp_client, &passive_tcp_client); // Custom 10-second timeout FTPClient ftp_client_custom(&tcp_client, &passive_tcp_client, 10000); ``` ``` -------------------------------- ### Create Directory on FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Creates a new directory on the FTP server using the MKD command. Returns true on a 257 success code. Has no effect if the directory exists. ```cpp if (ftp_client.create_directory("logs/2024")) { Serial.println("Directory created"); } else { Serial.printf("MKD failed, code: %d\n", ftp_client.m_last_error_code); } ``` -------------------------------- ### Connect and Authenticate to FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Connects to an FTP server using provided credentials and initiates the login handshake. Returns true on success, with the last error code available in `m_last_error_code` on failure. ```cpp WiFi.begin("MySSID", "MyPassword"); while (WiFi.status() != WL_CONNECTED) delay(500); WiFiClient tcp_client, passive_tcp_client; FTPClient ftp_client(&tcp_client, &passive_tcp_client); if (ftp_client.open("ftp.example.com", 21, "ftpuser", "secret")) { Serial.println("Connected to FTP server"); } else { Serial.printf("Connection failed, last error: %d\n", ftp_client.m_last_error_code); } ``` -------------------------------- ### create_directory Source: https://context7.com/exocet22/tinyftpclient/llms.txt Creates a new directory on the FTP server using the MKD command. ```APIDOC ## create_directory ### Description Create a new directory on the FTP server (MKD). Returns `true` on a 257 response. Has no effect if the directory already exists (server will return an error code, `m_last_error_code` will be set). ### Method Signature `bool create_directory(const char* directory_name)` ### Parameters * **directory_name** (const char*) - The name of the directory to create. ### Request Example ```cpp if (ftp_client.create_directory("logs/2024")) { Serial.println("Directory created"); } else { Serial.printf("MKD failed, code: %d\n", ftp_client.m_last_error_code); } ``` ``` -------------------------------- ### List Directory Contents with TinyFTPClient Source: https://context7.com/exocet22/tinyftpclient/llms.txt Lists the contents of a remote directory using the MLSD command. Populates a String array with raw MLSD response lines. Pass "" to list the current directory. Returns true on success. ```cpp String items[64]; if (ftp_client.list_directory("", items, 64)) { for (uint8_t i = 0; i < 64; i++) { if (items[i].length() > 0) { Serial.println(items[i]); // Example output line: // type=file;size=12345;modify=20240315143022; report.csv } } } else { Serial.println("MLSD failed"); } ``` -------------------------------- ### append_file (buffer) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends a raw byte buffer to an existing file on the FTP server using the APPE command, preserving existing content. ```APIDOC ## append_file (buffer) ### Description Appends a raw byte buffer to an existing file on the FTP server (APPE). Uses the FTP APPE command instead of STOR, so existing file content is preserved and new data is added at the end. ### Method Signature `bool append_file(const char* file_name, uint8_t* buffer, size_t buffer_size)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to append to. * **buffer** (uint8_t*) - A pointer to the byte buffer containing the data to append. * **buffer_size** (size_t) - The size of the buffer in bytes. ### Request Example ```cpp char line2[] = "Second measurement: 87\n"; if (ftp_client.append_file("sensor_log.txt", (uint8_t*)line2, strlen(line2) + 1)) { Serial.println("Append success"); } else { Serial.println("Append failed"); } ``` ``` -------------------------------- ### Append Raw Buffer to File Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends a raw byte buffer to an existing file on the FTP server using the APPE command. Existing content is preserved. ```cpp char line2[] = "Second measurement: 87\n"; if (ftp_client.append_file("sensor_log.txt", (uint8_t*)line2, strlen(line2) + 1)) { Serial.println("Append success"); } else { Serial.println("Append failed"); } ``` -------------------------------- ### Instantiate FTPClient with Custom Timeout Source: https://context7.com/exocet22/tinyftpclient/llms.txt Instantiates the FTP client with a custom timeout value (e.g., 10 seconds). ```cpp #include #include #include WiFiClient tcp_client; WiFiClient passive_tcp_client; // Custom 10-second timeout FTPClient ftp_client_custom(&tcp_client, &passive_tcp_client, 10000); ``` -------------------------------- ### write_file (SPIFFS path) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Upload a file from SPIFFS to the FTP server. Mounts SPIFFS, opens the local file for reading, and delegates to the File-based overload. The SPIFFS path follows the /filename.ext convention. ```APIDOC ## `write_file` (SPIFFS path) **`bool write_file(const char* file_name, const char* spiffs_file_name)`** — upload a file from SPIFFS to the FTP server. Mounts SPIFFS, opens the local file for reading, and delegates to the `File`-based overload. The SPIFFS path follows the `/filename.ext` convention. ```cpp // Assumes /data/reading.csv exists in SPIFFS if (ftp_client.write_file("remote_reading.csv", "/data/reading.csv")) { Serial.println("SPIFFS file uploaded"); } else { Serial.println("Upload failed"); } ``` ``` -------------------------------- ### open Source: https://context7.com/exocet22/tinyftpclient/llms.txt Connect and authenticate to an FTP server. Performs the full three-step FTP login handshake: TCP connect → server ready (220) → USER (331) → PASS (230). Returns true on success. The m_last_error_code public field holds the last FTP response code on failure. ```APIDOC ## `open` **`bool open(const char* server_address, uint16_t server_port, const char* user_name, const char* user_password)`** — connect and authenticate to an FTP server. Performs the full three-step FTP login handshake: TCP connect → server ready (220) → USER (331) → PASS (230). Returns `true` on success. The `m_last_error_code` public field holds the last FTP response code on failure. ```cpp WiFi.begin("MySSID", "MyPassword"); while (WiFi.status() != WL_CONNECTED) delay(500); WiFiClient tcp_client, passive_tcp_client; FTPClient ftp_client(&tcp_client, &passive_tcp_client); if (ftp_client.open("ftp.example.com", 21, "ftpuser", "secret")) { Serial.println("Connected to FTP server"); } else { Serial.printf("Connection failed, last error: %d\n", ftp_client.m_last_error_code); } ``` ``` -------------------------------- ### Change Directory with TinyFTPClient Source: https://context7.com/exocet22/tinyftpclient/llms.txt Changes the current working directory on the FTP server. Returns true on a 250 response. Subsequent file operations are relative to the new directory. ```cpp if (ftp_client.change_directory("logs/2024")) { Serial.println("Changed to logs/2024"); // Now write_file("march.csv", ...) goes to logs/2024/march.csv } else { Serial.println("CWD failed"); } ``` -------------------------------- ### write_file (buffer) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Upload a raw byte buffer to the FTP server as a new file (STOR). Opens passive mode, sends the STOR command, then streams the buffer in 512-byte blocks. Returns true on successful transfer and passive channel closure (226). ```APIDOC ## `write_file` (buffer) **`bool write_file(const char* file_name, uint8_t* buffer, size_t buffer_size)`** — upload a raw byte buffer to the FTP server as a new file (STOR). Opens passive mode, sends the STOR command, then streams the buffer in 512-byte blocks. Returns `true` on successful transfer and passive channel closure (226). ```cpp char text[] = "Hello from ESP32!\nSensor value: 42\n"; if (ftp_client.write_file("sensor_log.txt", (uint8_t*)text, strlen(text) + 1)) { Serial.println("Upload success"); } else { Serial.println("Upload failed"); } ``` ``` -------------------------------- ### write_file (File object) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Upload an already-opened Arduino File object to the FTP server. Useful when the caller manages file lifecycle manually or needs to use LittleFS or SD card files instead of SPIFFS. ```APIDOC ## `write_file` (File object) **`bool write_file(const char* file_name, File source_file)`** — upload an already-opened Arduino `File` object to the FTP server. Useful when the caller manages file lifecycle manually or needs to use LittleFS or SD card files instead of SPIFFS. ```cpp #include SPIFFS.begin(); File f = SPIFFS.open("/image.jpg", "r"); if (f && ftp_client.write_file("image.jpg", f)) { Serial.println("File object upload success"); } f.close(); ``` ``` -------------------------------- ### Remove Directory with TinyFTPClient Source: https://context7.com/exocet22/tinyftpclient/llms.txt Removes an empty directory from the FTP server. Returns true on a 250 response. Fails if the directory is not empty. ```cpp if (ftp_client.remove_directory("old_logs")) { Serial.println("Directory removed"); } else { Serial.println("RMD failed (may not be empty)"); } ``` -------------------------------- ### Download Remote File to SPIFFS Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file and saves it directly to SPIFFS. Streams data in 512-byte blocks. SPIFFS must be mounted. ```cpp // Downloads "firmware_config.json" from FTP server into SPIFFS at /config.json if (ftp_client.read_file("firmware_config.json", "/config.json")) { Serial.println("Config downloaded to SPIFFS"); } else { Serial.println("Download failed"); } ``` -------------------------------- ### Upload Raw Byte Buffer to FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Uploads a raw byte buffer to the FTP server as a new file. It opens passive mode, sends the STOR command, and streams the buffer in 512-byte blocks. Returns true on successful transfer and passive channel closure. ```cpp char text[] = "Hello from ESP32!\nSensor value: 42\n"; if (ftp_client.write_file("sensor_log.txt", (uint8_t*)text, strlen(text) + 1)) { Serial.println("Upload success"); } else { Serial.println("Upload failed"); } ``` -------------------------------- ### Download Remote File to File Object Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file into an already-opened writable `File` object. Ensure the File object is opened in write mode. ```cpp SPIFFS.begin(); File dest = SPIFFS.open("/downloaded.jpg", "w"); if (dest && ftp_client.read_file("photo.jpg", dest)) { Serial.println("Downloaded to File object"); } dest.close(); ``` -------------------------------- ### Append SPIFFS File to Remote File Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends the content of a local SPIFFS file to an existing remote file using the APPE command. SPIFFS must be mounted. ```cpp if (ftp_client.append_file("daily_log.txt", "/today.txt")) { Serial.println("SPIFFS append success"); } ``` -------------------------------- ### set_clients Source: https://context7.com/exocet22/tinyftpclient/llms.txt Reassign the control and passive TCP client pointers at runtime. Useful when the underlying Client objects need to be swapped (e.g., reconnecting after a network drop) without reconstructing the FTPClient instance. ```APIDOC ## `set_clients` **`void set_clients(Client* p_client, Client* p_passive_client)`** — reassign the control and passive TCP client pointers at runtime. Useful when the underlying `Client` objects need to be swapped (e.g., reconnecting after a network drop) without reconstructing the `FTPClient` instance. ```cpp WiFiClient new_control, new_passive; ftp_client.set_clients(&new_control, &new_passive); ``` ``` -------------------------------- ### Upload SPIFFS File to FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Uploads a file from the SPIFFS filesystem to the FTP server. The local file path should follow the '/filename.ext' convention. This function delegates to the File object overload. ```cpp // Assumes /data/reading.csv exists in SPIFFS if (ftp_client.write_file("remote_reading.csv", "/data/reading.csv")) { Serial.println("SPIFFS file uploaded"); } else { Serial.println("Upload failed"); } ``` -------------------------------- ### Upload Arduino File Object to FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Uploads an already-opened Arduino File object to the FTP server. This is useful for files stored on SPIFFS, LittleFS, or SD cards, where the caller manages the file lifecycle. ```cpp #include SPIFFS.begin(); File f = SPIFFS.open("/image.jpg", "r"); if (f && ftp_client.write_file("image.jpg", f)) { Serial.println("File object upload success"); } f.close(); ``` -------------------------------- ### read_file (buffer) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file into a local byte buffer using the RETR command. ```APIDOC ## read_file (buffer) ### Description Downloads a remote file into a local byte buffer (RETR). Receives up to `buffer_size` bytes. Content beyond the buffer size is silently discarded. Use this for small text responses, configuration files, or known-size payloads. ### Method Signature `bool read_file(const char* file_name, uint8_t* buffer, size_t buffer_size)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to download. * **buffer** (uint8_t*) - A pointer to the buffer where the file content will be stored. * **buffer_size** (size_t) - The maximum size of the buffer in bytes. ### Request Example ```cpp char result[256] = ""; if (ftp_client.read_file("config.txt", (uint8_t*)result, sizeof(result))) { Serial.printf("File contents: %s\n", result); } else { Serial.println("Download failed"); } ``` ``` -------------------------------- ### list_directory Source: https://context7.com/exocet22/tinyftpclient/llms.txt Lists the contents of a remote directory using the MLSD command. Populates the caller-provided String array with one entry per file/subdirectory. Each entry is a raw MLSD response line. Returns true on success. ```APIDOC ## list_directory ### Description Lists the contents of a remote directory using the MLSD command. ### Method Signature `bool list_directory(const char* directory_name, String* item_list, uint8_t item_list_count)` ### Parameters * **directory_name** (const char*) - The name of the directory to list. Pass `""` to list the current working directory. * **item_list** (String*) - An array of Strings to populate with the directory contents. * **item_list_count** (uint8_t) - The maximum number of items the `item_list` array can hold. ### Returns * `true` if the directory listing was successful. * `false` otherwise. ### Example ```cpp String items[64]; if (ftp_client.list_directory("", items, 64)) { for (uint8_t i = 0; i < 64; i++) { if (items[i].length() > 0) { Serial.println(items[i]); // Example output line: // type=file;size=12345;modify=20240315143022; report.csv } } } else { Serial.println("MLSD failed"); } ``` ``` -------------------------------- ### Read Remote File into Buffer Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file into a local byte buffer using the RETR command. Data exceeding buffer size is discarded. Suitable for small files. ```cpp char result[256] = ""; if (ftp_client.read_file("config.txt", (uint8_t*)result, sizeof(result))) { Serial.printf("File contents: %s\n", result); } else { Serial.println("Download failed"); } ``` -------------------------------- ### change_directory Source: https://context7.com/exocet22/tinyftpclient/llms.txt Changes the current working directory on the FTP server using the CWD command. Returns true on a 250 response. Subsequent file operations will be relative to the new working directory. ```APIDOC ## change_directory ### Description Changes the current working directory on the FTP server. ### Method Signature `bool change_directory(const char* directory_name)` ### Parameters * **directory_name** (const char*) - The name of the directory to change to. ### Returns * `true` if the directory was changed successfully (server responded with 250). * `false` otherwise. ### Example ```cpp if (ftp_client.change_directory("logs/2024")) { Serial.println("Changed to logs/2024"); // Now write_file("march.csv", ...) goes to logs/2024/march.csv } else { Serial.println("CWD failed"); } ``` ``` -------------------------------- ### Reassign TCP Clients at Runtime Source: https://context7.com/exocet22/tinyftpclient/llms.txt Reassigns the control and passive TCP client pointers for an existing FTPClient instance. This is useful for reconnecting without re-instantiating the client. ```cpp WiFiClient new_control, new_passive; ftp_client.set_clients(&new_control, &new_passive); ``` -------------------------------- ### Rename/Move File on FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Renames or moves a file on the FTP server using RNFR and RNTO commands. Returns true only if both commands succeed. ```cpp if (ftp_client.rename_file("octocat.jpg", "octocat_renamed.jpg")) { Serial.println("Rename success"); } else { Serial.println("Rename failed"); } ``` -------------------------------- ### read_file (File object) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file into an already opened and writable `File` object. ```APIDOC ## read_file (File object) ### Description Downloads a remote file into an already-opened writable `File` object. ### Method Signature `bool read_file(const char* file_name, File destination_file)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to download. * **destination_file** (File) - An opened `File` object in write mode where the downloaded content will be streamed. ### Request Example ```cpp SPIFFS.begin(); File dest = SPIFFS.open("/downloaded.jpg", "w"); if (dest && ftp_client.read_file("photo.jpg", dest)) { Serial.println("Downloaded to File object"); } dest.close(); ``` ``` -------------------------------- ### close Source: https://context7.com/exocet22/tinyftpclient/llms.txt Send the FTP QUIT command and disconnect the control TCP client. Should always be called after all FTP operations are complete to cleanly terminate the session. ```APIDOC ## `close` **`void close()`** — send the FTP QUIT command and disconnect the control TCP client. Should always be called after all FTP operations are complete to cleanly terminate the session. ```cpp ftp_client.close(); Serial.println("FTP session closed"); ``` ``` -------------------------------- ### read_file (SPIFFS path) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Downloads a remote file and saves its content directly to a specified path in SPIFFS. ```APIDOC ## read_file (SPIFFS path) ### Description Downloads a remote file and saves it directly to SPIFFS. Mounts SPIFFS, opens the destination path for writing, and streams the remote file to it in 512-byte blocks. ### Method Signature `bool read_file(const char* file_name, const char* spiffs_file_name)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to download. * **spiffs_file_name** (const char*) - The path in SPIFFS where the file will be saved. ### Request Example ```cpp // Downloads "firmware_config.json" from FTP server into SPIFFS at /config.json if (ftp_client.read_file("firmware_config.json", "/config.json")) { Serial.println("Config downloaded to SPIFFS"); } else { Serial.println("Download failed"); } ``` ``` -------------------------------- ### Append File Object to Remote File Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends the content of an open `File` object to an existing remote file. Ensure the File object is opened in read mode. ```cpp File extra = SPIFFS.open("/extra_data.bin", "r"); if (extra && ftp_client.append_file("archive.bin", extra)) { Serial.println("File object append success"); } extra.close(); ``` -------------------------------- ### append_file (SPIFFS path) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends the content of a local SPIFFS file to an existing remote file on the FTP server. ```APIDOC ## append_file (SPIFFS path) ### Description Appends a SPIFFS file's content to an existing remote file. Mounts SPIFFS and appends the entire local file to the specified remote file using APPE. ### Method Signature `bool append_file(const char* file_name, const char* spiffs_file_name)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to append to. * **spiffs_file_name** (const char*) - The path to the file in SPIFFS to append from. ### Request Example ```cpp if (ftp_client.append_file("daily_log.txt", "/today.txt")) { Serial.println("SPIFFS append success"); } ``` ``` -------------------------------- ### append_file (File object) Source: https://context7.com/exocet22/tinyftpclient/llms.txt Appends the content of an open `File` object to an existing remote file on the FTP server. ```APIDOC ## append_file (File object) ### Description Appends an open `File` object's content to an existing remote file. ### Method Signature `bool append_file(const char* file_name, File source_file)` ### Parameters * **file_name** (const char*) - The name of the file on the FTP server to append to. * **source_file** (File) - An opened `File` object representing the source of the data to append. ### Request Example ```cpp File extra = SPIFFS.open("/extra_data.bin", "r"); if (extra && ftp_client.append_file("archive.bin", extra)) { Serial.println("File object append success"); } extra.close(); ``` ``` -------------------------------- ### Delete File from FTP Server Source: https://context7.com/exocet22/tinyftpclient/llms.txt Permanently deletes a file from the FTP server using the DELE command. Returns true on a 250 success code. No confirmation prompt. ```cpp if (ftp_client.delete_file("temp_upload.txt")) { Serial.println("File deleted"); } else { Serial.printf("Delete failed, code: %d\n", ftp_client.m_last_error_code); } ``` -------------------------------- ### delete_file Source: https://context7.com/exocet22/tinyftpclient/llms.txt Permanently deletes a file from the FTP server using the DELE command. ```APIDOC ## delete_file ### Description Permanently delete a file from the FTP server (DELE). Returns `true` if the server responds with 250 (action completed). No confirmation prompt is issued. ### Method Signature `bool delete_file(const char* file_name)` ### Parameters * **file_name** (const char*) - The name of the file to delete. ### Request Example ```cpp if (ftp_client.delete_file("temp_upload.txt")) { Serial.println("File deleted"); } else { Serial.printf("Delete failed, code: %d\n", ftp_client.m_last_error_code); } ``` ``` -------------------------------- ### Close FTP Session Source: https://context7.com/exocet22/tinyftpclient/llms.txt Sends the QUIT command to the FTP server and disconnects the control TCP client, ensuring a clean session termination. ```cpp ftp_client.close(); Serial.println("FTP session closed"); ``` -------------------------------- ### remove_directory Source: https://context7.com/exocet22/tinyftpclient/llms.txt Removes an empty directory from the FTP server using the RMD command. Returns true on a 250 response. The directory must be empty. ```APIDOC ## remove_directory ### Description Removes an empty directory from the FTP server. ### Method Signature `bool remove_directory(const char* directory_name)` ### Parameters * **directory_name** (const char*) - The name of the directory to remove. ### Returns * `true` if the directory was removed successfully (server responded with 250). * `false` otherwise (e.g., if the directory is not empty). ### Example ```cpp if (ftp_client.remove_directory("old_logs")) { Serial.println("Directory removed"); } else { Serial.println("RMD failed (may not be empty)"); } ``` ``` -------------------------------- ### rename_file Source: https://context7.com/exocet22/tinyftpclient/llms.txt Renames or moves a file on the FTP server using the RNFR and RNTO commands. ```APIDOC ## rename_file ### Description Renames or moves a file on the FTP server using RNFR/RNTO commands. Issues RNFR (rename from, expects 350) then RNTO (rename to, expects 250). Returns `true` only if both commands succeed. ### Method Signature `bool rename_file(const char* from, const char* to)` ### Parameters * **from** (const char*) - The current name of the file. * **to** (const char*) - The new name for the file. ### Request Example ```cpp if (ftp_client.rename_file("octocat.jpg", "octocat_renamed.jpg")) { Serial.println("Rename success"); } else { Serial.println("Rename failed"); } ``` ``` -------------------------------- ### get_last_modified_time Source: https://context7.com/exocet22/tinyftpclient/llms.txt Retrieves the last modification timestamp of a remote file using the MDTM command. ```APIDOC ## get_last_modified_time ### Description Retrieve the last modification timestamp of a remote file (MDTM). The server returns a timestamp string in the format `YYYYMMDDHHMMSS`. The result is written into the caller-provided buffer. Returns `true` on a 213 response. ### Method Signature `bool get_last_modified_time(const char* file_name, char* result)` ### Parameters * **file_name** (const char*) - The name of the file to query. * **result** (char*) - A buffer to store the timestamp string. The buffer must be large enough to hold the timestamp (e.g., 32 bytes). ### Request Example ```cpp char timestamp[32] = ""; if (ftp_client.get_last_modified_time("report.csv", timestamp)) { // timestamp format: "20240315143022" Serial.printf("Last modified: %s\n", timestamp); // Expected output: Last modified: 20240315143022 } else { Serial.println("MDTM failed"); } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.