zoukankan      html  css  js  c++  java
  • FATFS 初学之 f_open/ f_close

    f_open:

      1 /*-----------------------------------------------------------------------*/
      2 /* Open or Create a File                                                 */
      3 /*-----------------------------------------------------------------------*/
      4 
      5 FRESULT f_open (
      6     FIL *fp,            /* Pointer to the blank file object */
      7     const TCHAR *path,    /* Pointer to the file name */
      8     BYTE mode            /* Access mode and file open mode flags */
      9 )
     10 {
     11     FRESULT res;
     12     DIR dj;
     13     BYTE *dir;
     14     DEF_NAMEBUF;
     15 
     16 
     17     fp->fs = 0;            /* Clear file object */
     18 
     19 #if !_FS_READONLY
     20     mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
     21     res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
     22 #else
     23     mode &= FA_READ;
     24     res = chk_mounted(&path, &dj.fs, 0);
     25 #endif
     26     INIT_BUF(dj);
     27     if (res == FR_OK)
     28         res = follow_path(&dj, path);    /* Follow the file path */
     29     dir = dj.dir;
     30 
     31 #if !_FS_READONLY    /* R/W configuration */
     32     if (res == FR_OK) {
     33         if (!dir)    /* Current dir itself */
     34             res = FR_INVALID_NAME;
     35 #if _FS_SHARE
     36         else
     37             res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
     38 #endif
     39     }
     40     /* Create or Open a file */
     41     if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
     42         DWORD dw, cl;
     43 
     44         if (res != FR_OK) {                    /* No file, create new */
     45             if (res == FR_NO_FILE)            /* There is no file to open, create a new entry */
     46 #if _FS_SHARE
     47                 res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
     48 #else
     49                 res = dir_register(&dj);
     50 #endif
     51             mode |= FA_CREATE_ALWAYS;        /* File is created */
     52             dir = dj.dir;                    /* New entry */
     53         }
     54         else {                                /* Any object is already existing */
     55             if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {    /* Cannot overwrite it (R/O or DIR) */
     56                 res = FR_DENIED;
     57             } else {
     58                 if (mode & FA_CREATE_NEW)    /* Cannot create as new file */
     59                     res = FR_EXIST;
     60             }
     61         }
     62         if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {    /* Truncate it if overwrite mode */
     63             dw = get_fattime();                    /* Created time */
     64             ST_DWORD(dir+DIR_CrtTime, dw);
     65             dir[DIR_Attr] = 0;                    /* Reset attribute */
     66             ST_DWORD(dir+DIR_FileSize, 0);        /* size = 0 */
     67             cl = LD_CLUST(dir);                    /* Get start cluster */
     68             ST_CLUST(dir, 0);                    /* cluster = 0 */
     69             dj.fs->wflag = 1;
     70             if (cl) {                            /* Remove the cluster chain if exist */
     71                 dw = dj.fs->winsect;
     72                 res = remove_chain(dj.fs, cl);
     73                 if (res == FR_OK) {
     74                     dj.fs->last_clust = cl - 1;    /* Reuse the cluster hole */
     75                     res = move_window(dj.fs, dw);
     76                 }
     77             }
     78         }
     79     }
     80     else {    /* Open an existing file */
     81         if (res == FR_OK) {                        /* Follow succeeded */
     82             if (dir[DIR_Attr] & AM_DIR) {        /* It is a directory */
     83                 res = FR_NO_FILE;
     84             } else {
     85                 if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
     86                     res = FR_DENIED;
     87             }
     88         }
     89     }
     90     if (res == FR_OK) {
     91         if (mode & FA_CREATE_ALWAYS)            /* Set file change flag if created or overwritten */
     92             mode |= FA__WRITTEN;
     93         fp->dir_sect = dj.fs->winsect;            /* Pointer to the directory entry */
     94         fp->dir_ptr = dir;
     95 #if _FS_SHARE
     96         fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
     97         if (!fp->lockid) res = FR_INT_ERR;
     98 #endif
     99     }
    100 
    101 #else                /* R/O configuration */
    102     if (res == FR_OK) {                    /* Follow succeeded */
    103         if (!dir) {                        /* Current dir itself */
    104             res = FR_INVALID_NAME;
    105         } else {
    106             if (dir[DIR_Attr] & AM_DIR)    /* It is a directory */
    107                 res = FR_NO_FILE;
    108         }
    109     }
    110 #endif
    111     FREE_BUF();
    112 
    113     if (res == FR_OK) {
    114         fp->flag = mode;                    /* File access mode */
    115         fp->sclust = LD_CLUST(dir);            /* File start cluster */
    116         fp->fsize = LD_DWORD(dir+DIR_FileSize);    /* File size */
    117         fp->fptr = 0;                        /* File pointer */
    118         fp->dsect = 0;
    119 #if _USE_FASTSEEK
    120         fp->cltbl = 0;                        /* Normal seek mode */
    121 #endif
    122         fp->fs = dj.fs; fp->id = dj.fs->id;    /* Validate file object */
    123     }
    124 
    125     LEAVE_FF(dj.fs, res);
    126 }
    View Code

    函数功能:创建/打开一个用于访问文件的文件对象

    描述:如果函数成功,则创建一个文件对象。该文件对象被后续的读/写函数用来访问文件。如果想要关闭一个打开的文件对象,则使用f_close函数。如果不关闭修改后的文件,那么文件可能会崩溃。

    在使用任何文件函数之前,必须使用 f_mount函数为驱动器注册一个工作区。只有这样,其他文件函数才能正常工作。

    将打开的文件名、文件目录及读写属性等装入 fp,为后续操作做准备。

    f_close:

     1 /*-----------------------------------------------------------------------*/
     2 /* Close File                                                            */
     3 /*-----------------------------------------------------------------------*/
     4 
     5 FRESULT f_close (
     6     FIL *fp        /* Pointer to the file object to be closed */
     7 )
     8 {
     9     FRESULT res;
    10 
    11 #if _FS_READONLY
    12     FATFS *fs = fp->fs;
    13     res = validate(fs, fp->id);
    14     if (res == FR_OK) fp->fs = 0;    /* Discard file object */
    15     LEAVE_FF(fs, res);
    16 
    17 #else
    18     res = f_sync(fp);        /* Flush cached data */
    19 #if _FS_SHARE
    20     if (res == FR_OK) {        /* Decrement open counter */
    21 #if _FS_REENTRANT
    22         res = validate(fp->fs, fp->id);
    23         if (res == FR_OK) {
    24             res = dec_lock(fp->lockid);    
    25             unlock_fs(fp->fs, FR_OK);
    26         }
    27 #else
    28         res = dec_lock(fp->lockid);
    29 #endif
    30     }
    31 #endif
    32     if (res == FR_OK) fp->fs = 0;    /* Discard file object */
    33     return res;
    34 #endif
    35 }
    View Code

    函数功能:关闭一个已打开的文件

    描述:f_close函数关闭一个打开的文件对象。无论向文件写入任何数据,文件的缓存信息都将被写回到磁盘。该函数成功后,文件对象不再有效,并且可以被丢弃。如果文件对象是在只读模式下打开的,不需要使用该函数,也能被丢弃。

    例:

     1 FATFS fs;        /* 逻辑驱动器的工作区(文件系统对象) */
     2 FIL fsrc;        /* 文件对象 */
     3 FRESULT res;    /* FatFs 函数公共结果代码 */
     4 
     5 void main(void)
     6 {
     7     // 设备初始化...
     8     
     9     f_mount(0,&fs);
    10     res = f_open(&fdst,"0:/Demo.TXT", FA_WRITE | FA_READ);
    11     if(FR_OK == res)
    12     {
    13         // ...
    14         f_close(&fdst);
    15     }
    16     else
    17     {
    18         // ...
    19     }
    20     
    21     f_mount(0, NULL);
    22 }
  • 相关阅读:
    鼠标滑动显示层
    软件过程+改进 +UML
    接口和抽象类的区别
    SQL SERVER – Difference Between EXEC and EXECUTE vs EXEC() – Use EXEC/EXECUTE for SP always
    XDocument.Parse Method (String)
    Robocopy use case
    Two Solutions to fix issue: ORDER BY items must appear in the select list if the statement contains a UNION, ...
    [转载]:SQL Server 连接字符串和身份验证
    Insert Data From One Table to Another
    volatile (C# Reference)
  • 原文地址:https://www.cnblogs.com/Danhuise/p/3909430.html
Copyright © 2011-2022 走看看