ffxz 发表于 2010-2-12 00:15:28

如何在RT-Thread中进行文件写入操作

这几天几位同学来问RT-Thread中文件读写接口是如何的,因为要写入到SD卡中,试过好几次都有问题,不知道写文件的操作应该如何进行,下面用一个例子解释文件写的操作流程(readwrite.c例程,可在STM3210目录下的project_filesystem工程使用)。这个例程建议使用ELM FatFs文件系统,因为以后ELM FatFs文件系统会逐渐取代以前的EFSL文件系统:

#include <rtthread.h>
#include <dfs_posix.h>

/* TEST_FN是测试用的文件名,采用宏定义方便修改*/
#define TEST_FN                "/test.dat"
/* 保存测试用到的数据,这里采用全局类型的变量以避免占用栈空间 */
static char test_data, buffer;

/* 文件读写测试 */
void readwrite(const char* filename)
{
        int fd;
        int index, length;

        /* 只写,创建和截零 模式打开 */
        fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);
        if (fd < 0)
        {
                rt_kprintf("open file for write failed\n");
                return;
        }

        /* 准备写入数据 */
        for (index = 0; index < sizeof(test_data); index ++)
        {
                test_data = index + 27;
        }

        /* 写入数据 */
        length = write(fd, test_data, sizeof(test_data));
        if (length != sizeof(test_data))
        {
                rt_kprintf("write data failed\n");
                close(fd);
                return;
        }

        /* 关闭文件 */
        close(fd);

        /* 只写并在末尾添加打开 */
        fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0);
        if (fd < 0)
        {
                rt_kprintf("open file for append write failed\n");
                return;
        }

        length = write(fd, test_data, sizeof(test_data));
        if (length != sizeof(test_data))
        {
                rt_kprintf("append write data failed\n");
                close(fd);
                return;
        }
        /* 关闭文件 */
        close(fd);

        /* 只读打开进行数据校验 */
        fd = open(TEST_FN, O_RDONLY, 0);
        if (fd < 0)
        {
                rt_kprintf("check: open file for read failed\n");
                return;
        }

        length = read(fd, buffer, sizeof(buffer));
        if (length != sizeof(buffer))
        {
                rt_kprintf("check: read file failed\n");
                close(fd);
                return;
        }
        for (index = 0; index < sizeof(test_data); index ++)
        {
                if (test_data != buffer)
                {
                        rt_kprintf("check: check data failed at %d\n", index);
                        close(fd);
                        return;
                }
        }

        length = read(fd, buffer, sizeof(buffer));
        if (length != sizeof(buffer))
        {
                rt_kprintf("check: read file failed\n");
                close(fd);
                return;
        }
        for (index = 0; index < sizeof(test_data); index ++)
        {
                if (test_data != buffer)
                {
                        rt_kprintf("check: check data failed at %d\n", index);
                        close(fd);
                        return;
                }
        }
        /* 检查数据完毕,关闭文件 */
        close(fd);
        /* 打印结果 */
        rt_kprintf("read/write done.\n");
}

#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test);
#endif

上面的例子中和写相关的主要是两个open函数,但是使用的参数并不相同。
第一个open:
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);

其中
O_WRONLY指明这是一个写入方式的打开模式;
O_CREAT指明如果文件不存在则创建文件
O_TRUNC指明如果文件存在,则把文件的长度归零,然后打开
最后的参数0是为了和POSIX标准兼容的,原意指明创建的模式(读、写、可执行等等),因为RT-Thread不支持多用户系统,所以默认忽略这个参数。

第二个open:
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0);

和第一个open相比,只是把O_TRUNC参数更改为O_APPEND,即更改为打开后,如果再进行写入,将从文件的末尾位置开始写。

这两种使用方法能够覆盖大多数使用情况,如果总是记录新的文件,那么用前一种方式打开文件然后写入。如果是保留老的记录,仅把新的记录添加到文件末尾,那么使用第二种即可。RT-Thread的文件目录操作接口是和标准的POSIX接口相兼容的,所以在使用的时候也可以参照POSIX的使用方法进行操作。在google svn的trunk\example\file目录中有更多和文件操作相关的例程。

tedden 发表于 2010-2-12 10:26:37

顶,开学后尝试下这个系统~

fzxuecumt 发表于 2010-5-5 17:33:36

RT—Thread 确实很强大。

loongsuns 发表于 2010-5-7 17:41:36

读文件的时候移动文件指针用什么指令?

aozima 发表于 2010-5-7 17:55:07

POSIX兼容

litteworm 发表于 2010-5-7 18:33:09

顶一个 例程越来越丰富了
页: [1]
查看完整版本: 如何在RT-Thread中进行文件写入操作