Opening, Reading and Writing Files - POSIX

When an application needs to access a file, it must first open it using fs_fopen():

p_file = fs_fopen("\\file.txt", /* file name   */
                  "w+");        /* mode string */
if (p_file == (FS_FILE *)0) {
    /* $$$$ Handle error */
}

The return value of this function should always be verified as non-NULL before the application proceeds to access the file. The first argument of this function is the path of the file; if working directories are disabled, this must be the absolute file path, beginning with either a volume name or a ‘\’ (see µC/FS File and Directory Names and Paths). The second argument of this function is a string indicating the mode of the file; this must be one of the strings shown in Table - fs_fopen() mode strings interpretations. Note that in all instances, the ‘b’ (binary) option has no affect on the behavior of file accesses.

Table - fs_fopen() mode strings interpretations

fs_fopen() Mode String

Read?

Write?

Truncate?

Create?

Append?

“r” or “rb”

Yes

No

No

No

No

“w” or “wb”

No

Yes

Yes

Yes

No

“a” or “ab”

No

Yes

No

Yes

Yes

“r+” or “rb+” or “r+b”

Yes

Yes

No

No

No

“w+” or “wb+” or “w+b”

Yes

Yes

Yes

Yes

No

“a+” or “ab+” or “a+b”

Yes

Yes

No

Yes

Yes


After a file is opened, any of the file access functions valid for that its mode can be called. The most commonly used functions are fs_fread() and fs_fwrite(), which read or write a certain number of ‘items’ from a file:

cnt = fs_fread(p_buf,   /* pointer to buffer */
               1,       /* size of each item */
               100,     /* number of items   */
               p_file); /* pointer to file   */

The return value, the number of items read (or written), should be less than or equal to the third argument. If the operation is a read, this value may be less than the third argument for one of two reasons. First, the file could have encountered the end-of-file (EOF), which means that there is no more data in the file. Second, the device could have been removed, or some other error could have prevented the operation. To diagnose the cause, the fs_feof() function should be used. This function returns a non-zero value if the file has encountered the EOF.

Once the file access is complete, the file must be closed; if an application fails to close files, then the file system suite resources such as file objects may be depleted.

An example of reading a file is given below:

Listing - Example file read
void  App_Fnct (void)
{
    FS_FILE         *p_file;
    fs_size_t        cnt;
    unsigned  char   buf[50];
    .
    .
    .
    
    p_file = fs_fopen("\\file.txt", "r");          /* Open file.                           */ 
           
    if (p_file != (FS_FILE *)0) {                  /* If file is opened ...                */
                                                   /* ... read from file.	               */
        do {
            cnt = fs_fread(&buf[0], 1, sizeof(buf), p_file);
            if (cnt > 0) {
                APP_TRACE_INFO(("Read %d bytes.\r\n", cnt));
            }
        } while (cnt >= sizeof(buf));
        eof = fs_feof(p_file);                     /* Chk for EOF.	                       */
        if (eof != 0) {                            (1)
            APP_TRACE_INFO(("Reached EOF.\r\n"));
        } else {
            err = fs_ferror(p_file);               /* Chk for error.                      */
            if (err != 0) {                        (2)
                APP_TRACE_INFO(("Read error.\r\n"));
            } 
        }
        fs_fclose(p_file);                         /* Close file.                         */
    } else {
        APP_TRACE_INFO(("Could not open \"\\file.txt\".\r\n"));
    }
    .
    .
    .
}


(1) To determine whether a file read terminates because of reaching the EOF or a device error/removal, the EOF condition should be checked using fs_feof().

(2) In most situations, either the EOF or the error indicator will be set on the file if the return value of fs_fread() is smaller than the buffer size. Consequently, this check is unnecessary.