File operations
This page has been automatically translated using the Google Translate API services. We are working on improving texts. Thank you for your understanding and patience.
Provides high level functions on Files and directories.
Functions
bool_t | hfile_dir (...) |
bool_t | hfile_dir_create (...) |
bool_t | hfile_dir_destroy (...) |
ArrSt(DirEntry)* | hfile_dir_list (...) |
void | hfile_dir_entry_remove (...) |
Date | hfile_date (...) |
bool_t | hfile_dir_sync (...) |
bool_t | hfile_exists (...) |
bool_t | hfile_is_uptodate (...) |
bool_t | hfile_copy (...) |
Buffer* | hfile_buffer (...) |
String* | hfile_string (...) |
Stream* | hfile_stream (...) |
bool_t | hfile_from_string (...) |
bool_t | hfile_from_data (...) |
bool_t | hfile_dir_loop (...) |
String* | hfile_appdata (...) |
String* | hfile_home_dir (...) |
Although in Files and directories we already saw how to access the file system at a low level, sometimes certain high-level operations are necessary on the data on disk. The mere act of completely deleting a directory has many individual low-level operations associated with it. The Core library, through <hfile.h>
provides certain utilities that can simplify our lives at certain times.
- Use hfile_dir_create to create a directory, also creating its predecessors if they don't exist.
- Use hfile_dir_destroy to recursively delete a directory and all its contents.
- Use hfile_dir_sync to synchronize the contents of two directories. Something similar to Unix
rsync
. - Use hfile_dir_loop to go deep through a directory (Listing 1).
- Use hfile_buffer to load the contents of a file into memory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
typedef struct _query_t Query; static void i_OnEntry(Query *query, Event *e) { const EvFileDir *p = event_params(e, EvFileDir); // First level (year) if (p->depth == 0) { // The entry is a directory if (event_type(e) == ekEENTRY) { bool_t *enter = event_result(e, bool_t); int16_t year = str_to_i16(p->filename, 10, NULL); // The loop enter in this subdir (depth 1) if (i_process_year(query, year) == TRUE) *enter = TRUE; else *enter = FALSE; } } // Second level (month) else if (p->depth == 1) { // The entry is a directory if (event_type(e) == ekEENTRY) { bool_t *enter = event_result(e, bool_t); uint8_t month = str_to_u8(p->filename, 10, NULL); // The loop enter in this subdir (depth 2) if (i_process_month(query, month) == TRUE) *enter = TRUE; else *enter = FALSE; } } // Third level (files) else if (p->depth == 2) { // The entry is a file if (event_type(e) == ekEFILE) i_process_file(query, p->pathname); } } /*---------------------------------------------------------------------------*/ Query query = i_init_query(&query); hfile_dir_loop("main_path", listener(&query, i_OnEntry, Query), TRUE, FALSE, NULL); |
hfile_dir ()
Check if the path is a directory.
bool_t hfile_dir(const char_t *pathname);
pathname | Name of the path to check. Filename and pathname. |
Return
TRUE
if pathname
is a directory. If it does not exist or is a file FALSE
.
hfile_dir_create ()
Create all intermediate subdirectories of a path.
bool_t hfile_dir_create(const char_t *pathname, ferror_t *error);
1 2 3 |
// C:\dir1 doesn't exist. bool_t ok = hfile_dir_create("C:\dir1\dir2\dir3\dir4\dir5"); ok = TRUE |
pathname | Name of the path to create. Filename and pathname. |
error | Error code if the function fails. Can be |
Return
TRUE
if the entire path has been created, otherwise FALSE
.
hfile_dir_destroy ()
Recursive destroy a directory and all its contents.
bool_t hfile_dir_destroy(const char_t *pathname, ferror_t *error);
pathname | Directory path to destroy. Filename and pathname. |
error | Error code if the function fails. Can be |
Return
TRUE
if the directory has been destroyed, or FALSE
if there has been an error.
hfile_dir_list ()
Get a list of the contents of a directory.
ArrSt(DirEntry)* hfile_dir_list(const char_t *pathname, ferror_t *error);
pathname | Directory path to list. Filename and pathname. |
error | Error code if the function fails. Can be |
Return
Array of DirEntry with the content. It must be destroyed with arrst_destroy(&array, hfile_dir_entry_remove, DirEntry)
when it is no longer necessary.
hfile_dir_entry_remove ()
Free the memory of an item in the directory listing.
void hfile_dir_entry_remove(DirEntry *entry);
entry | Element. |
Remarks
See hfile_dir_list.
hfile_date ()
Gets the most recent modification date of a file or directory.
Date hfile_date(const char_t *pathname, const bool_t recursive);
pathname | Path to file or directory. Filename and pathname. |
recursive | If |
Return
The modification date. If pathname
does not exist kDATE_NULL.
Remarks
If pathname
is a directory, the modification dates of the files will be considered as well, not just the directory itself.
hfile_dir_sync ()
Synchronize the contents of two directories.
bool_t hfile_dir_sync(const char_t *src, const char_t *dest, const bool_t recursive, const bool_t remove_in_dest, const char_t **except, const uint32_t except_size, ferror_t *error);
src | Source directory. |
dest | Destination directory. |
recursive | If |
remove_in_dest | If |
except | List of file/directory names that will remain intact in |
except_size | Array |
error | Error code if the function fails. Can be |
Return
TRUE
if everything went well, FALSE
if there has been an error.
Remarks
If a file is in src
and not in dest
, is copied to dest
. If a file is newer in src
it is also copied in dest
. If a file exists in dest
but not in src
and remove_in_dest
is TRUE
, will be removed from dest
. If the file exists in except
array it will not be taken into account to copy or delete. If recursive
is TRUE
subdirectories will be processed in this way: If both subdirs exist in src
and dest
the same logic described here will be executed in both subdirs. If the subdir exists in src
but not in dest
, will be copied in its entirety to dest
. If it exists in dest
and not in src
and remove_in_dest
is TRUE
will be completely removed from dest
.
hfile_exists ()
Check if pathname
exists in the file system.
bool_t hfile_exists(const char_t *pathname, file_type_t *file_type);
pathname | Path of the directory or file to check. Filename and pathname. |
file_type | Type of file. It can be |
Return
TRUE
if pathname
exists, FALSE
if not.
hfile_is_uptodate ()
Check if a file is up to date. Consider that dest
is a copy or depends on src
.
bool_t hfile_is_uptodate(const char_t *src, const char_t *dest);
src | Source file pathname. |
dest | Destiny file pathname. |
Return
TRUE
if dest
exists and is more recent than src
, otherwise FALSE
.
hfile_copy ()
Copy a file from one location to another.
bool_t hfile_copy(const char_t *src, const char_t *dest, ferror_t *error);
1 2 |
hfile_copy("/home/john/image.png", "/home/john/images", NULL); // image.png hfile_copy("/home/john/image.png", "/home/john/images/party.png", NULL); // party.png |
src | Pathname of the file to copy. Filename and pathname. |
dest | Copy destination. If it is a directory it will have the same filename as the source. Otherwise, the copy will be made with another file name. |
error | Error code if the function fails. It can be |
Return
TRUE
if the copy was successful. Otherwise FALSE
.
hfile_buffer ()
Create a buffer with the contents of a file on disk.
Buffer* hfile_buffer(const char_t *pathname, ferror_t *error);
pathname | File path to load. |
error | Error code if the function fails. It can be |
Return
The buffer with the file data or NULL
if the function fails.
Remarks
It does not work with files larger than 4Gb (32-bit).
hfile_string ()
Create a string with the contents of a file on disk.
String* hfile_string(const char_t *pathname, ferror_t *error);
pathname | File path to load. |
error | Error code if the function fails. It can be |
Return
The string object with the text file data or NULL
if the function fails.
Remarks
It does not work with files larger than 4Gb (32-bit).
hfile_stream ()
Create a Memory stream and initializes it with the contents of a file.
Stream* hfile_stream(const char_t *pathname, ferror_t *error);
pathname | File path to load. |
error | Error code if the function fails. It can be |
Return
The stream initialized with the file data or NULL
if the function fails.
Remarks
It does not work with files larger than 4Gb (32-bit).
hfile_from_string ()
Create a file on disk with the contents of a Strings.
bool_t hfile_from_string(const char_t *pathname, const String *str, ferror_t *error);
pathname | File path to save. |
str | String to save to file. |
error | Error code if the function fails. It can be |
Return
TRUE
if the file has been created successfully. Otherwise FALSE
.
hfile_from_data ()
Create a file on disk with the contents of a generic block of memory.
bool_t hfile_from_data(const char_t *pathname, const byte_t *data, const uint32_t size, ferror_t *error);
pathname | File path to save. |
data | Block to save in the file. |
size | Block size in bytes. |
error | Error code if the function fails. It can be |
Return
TRUE
if the file has been created successfully. Otherwise FALSE
.
hfile_dir_loop ()
Browse all the files in a directory.
bool_t hfile_dir_loop(const char_t *pathname, Listener *listener, const bool_t subdirs, const bool_t hiddens, ferror_t *error);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
static void i_OnEntry(App *app, Event *event) { uint32_t type = event_type(event); const EvFileDir *p = event_params(event, EvFileDir); if (type == ekEFILE) { bstd_printf("File: %s\n", p->pathname); // Abort the directory loop if (app->more == FALSE) { bool_t *more = event_result(event, bool_t); *more = FALSE; } } else if (type == ekEENTRY) { if (app->direntry == TRUE) { bstd_printf("Entering: %s\n", params->pathname); } else { bool_t *entry = event_result(event, bool_t); *entry = FALSE; } } else if (type == ekEEXIT) { bstd_printf("Exiting: %s\n", params->pathname); } } hfile_dir_loop("/home/john/personal", listener(app, i_OnEntry, App), TRUE, FALSE, NULL); |
pathname | Directory Path. Filename and pathname. |
listener | Callback function to be called for each directory file. |
subdirs | If |
hiddens | If |
error | Error code if the function fails. It can be |
Return
TRUE
tf the loop has been successfully completed. FALSE
if an error has occurred.
Remarks
For each file, an event will be sent to listener
. Will be of type ekEFILE for regular files, ekEENTRY when enters a subdirectory and ekEEXIT when leaves it. The file attributes are sent in the event parameter as a EvFileDir object. The tour will continue until all files/subdirectories have been processed or returned FALSE
in event_result . This controlled output will not be considered an error and this function will return TRUE
.
hfile_appdata ()
Get the full path of a data file or application settings.
String* hfile_appdata(const char_t *pathname);
1 2 3 4 5 |
String *fname = hfile_appdata("gui/preferences.cfg"); fname = "C:\Users\USER\AppData\Roaming\MyApp\gui\preferences.cfg" (in Windows operating system) ... Stream *out = stm_to_file(tc(fname), NULL); |
pathname | Relative file path. |
Return
The full path to the configuration file.
Remarks
In many cases, applications need to create configuration files to remember user preferences or other data between sessions Home and AppData. This function adds a relative path and file name and ensures that all intermediate directories will exist.
hfile_home_dir ()
Get the full path to a file in the user's (home) directory.
String* hfile_home_dir(const char_t *path);
path | Relative path from the home directory. |
Return
Absolute file path.