CODESYS开发教程10-文件读写(SysFile库)
今天继续我们的小白教程,老鸟就不要在这浪费时间了:loveliness:。
前面一期我们介绍了CODESYS的文件操作库CAA File。这一期主要介绍CODESYS的SysFile库所包含的文件读写功能块,主要包括文件路径、名称、大小的获取以及文件的创建、打开、读、写、拷贝和删除功能等。
一、SysFile库简介
与上一期介绍的目录和文件操作库CAA File不同,SysFile属于CODESYS比较底层的库,其中结构和功能块的定义与C语言非常接近。使用该库需要在“库管理器”中添加SysFile库,这里使用的是3.5.15版本。
需要注意的是,SysFile库中所有功能均为函数(FUNCTION),与CAA File库中的功能块(FUNCTION_BLOCK)是不同。函数可以直接使用,而功能块需要先声明后使用。因为CODESYS的函数内部的变量在运行后是不会保留的,这个与功能块是不同。使用的时候要分清楚,避免因为初始状态不同导致的问题。
二、SysFile库的主要功能块
提供对运行时系统的文件功能的访问。仅能进行文件相关的操作。
1.基本定义
(1)文件访问模式ACCESS_MODE
定义文件打开的模式。
注意:对于所有*_PLUS模式,读取文件后,只能在调用SysFileGetPos或SysFileSetPos后才能进行写入!如果在SysFileRead之后立即调用SysFileWrite,则文件指针可能位于无效位置!正确的使用方式如下:
SysFileRead();
SysFileGetPos();
SysFileWrite();
(2)文件的时间戳SYS_FILETIME
定义文件的时间戳结构。
tCreation:文件创建时间。
tLastAccess:访问文件的时间。
tLastModification:上次修改的时间。
(3)文件状态SYS_FILE_STATUS
定义指定文件的实际文件状态。
(4)错误码定义Errors
此错误码定义位于CmpErrors库中,文件读写中常用的如下表所示:
由于错误定义较多,这里只列了比较常用的几个,上表中没有列出的可以参考官方文档。
2.文件操作函数
文件操作函数如下表:
3.常用的函数介绍
SysFile库文件操作函数的参数比较类似,下面对几个常用的函数进行介绍。
(1)SysFileOpen
szFile:文件名称。可以包含绝对或相对路径,注意路径需要用斜杠“/”表示,不能用反斜杠“\”。
am:打开模式,类型为SysFile.ACCESS_MODE。
pResult:返回运行系统错误代码,类型为POINTER TO RTS_IEC_RESULT,含义在CMPErrors库中定义,见第一部分介绍。
返回值:成功则返回文件句柄,类型为SysFile.RTS_IEC_HANDLE,失败则返回RTS_INVALID_HANDLE。
(2)SysFileClose、SysFileFlush
hFile:文件句柄,类型为SysFile.RTS_IEC_HANDLE。
返回值:返回运行系统错误代码,类型为RTS_IEC_RESULT。
(3)SysFileRead和SysFileWrite
hFile:文件句柄。
pbyBuffer:指向读或者写缓冲区首地址,类型为POINTER TO BYTE。
ulSize:需要读取或写入的字节数。注意必须小于等于缓冲区尺寸。
pResult:返回运行系统错误代码。
返回值:成功则返回读取或写入的字节,失败则返回0。数据类型为_XWORD,实际与DWORD等价。
(4)SysFileGetSize
szFileName:文件名称
pResult:返回运行系统错误代码。
返回值:文件尺寸。
(5)SysFileGetTime
szFileName:文件名称
ptFileTime:文件时间,类型为POINTER TO SYS_FILETIME。
返回值:返回运行系统错误代码,类型为SysFile.RTS_IEC_RESULT。
注意:以上函数中凡是类型为RTS_IEC_RESULT的返回值,如果是在函数中作为输入,则需要定义为指针POINTER TO RTS_IEC_RESULT或者使用ADR()来获取错误码;如果作为函数返回值,则为SysFile.RTS_IEC_RESULT。
三、SysFile库使用示例
SysFile库的函数可以直接一起顺序使用,也可以像CAA File库中的功能块一样按状态机的方式进行操作。以下示例为文件写入的分步操作。本次测试使用的控制器是禾川的Q0,使用其它控制器时需要正确指定可进行读写操作的目录位置。
程序变量定义如下:
PROGRAM testSysFile
VAR
bExecute : BOOL;
szFileName : STRING:='/testfile.txt';
pbyBuffer : POINTER TO BYTE;
ulSize : DWORD;
ErrorCode : INT;
Done : BOOL;
stContent : STRING:='hello everyone!';
Mode : SysFile.ACCESS_MODE := 1; //0-AM_READ; 1-AM_WRITE; 2-AM_APPEND; 3-AM_READ_PLUS; 4-AM_WRITE_PLUS; 5-AM_APPEND_PLUS
iStep : INT := 0; //运转流程
OP_TRIG : R_TRIG;
bError : BOOL;
hFile : SysFile.RTS_IEC_HANDLE;
pRes : SysFile.RTS_IEC_RESULT;
iRet : DWORD;
END_VAR
程序如下:
bExecute:=TRUE;
OP_TRIG(CLK := bExecute);
pbyBuffer:=ADR(stContent);
ulSize:=SIZEOF(stContent);
IF OP_TRIG.Q AND iStep=0 THEN
iStep := 1;
END_IF
CASE iStep OF
0:
IF bExecute=FALSE THEN
Done := FALSE;
ErrorCode := 0;
bError := FALSE;
END_IF
1:
hFile := SysFileOpen(szFileName, Mode, ADR(pRes)); //打开文件
IF (pRes<>0 OR hFile=SysFile.RTS_INVALID_HANDLE) THEN
bError := TRUE;
ELSE
iStep := 2;
END_IF
2:
iRet:=SysFileWrite(hFile, pbyBuffer, ulSize, ADR(pRes)); //内容写入文件
IF (iRet=0) THEN
SysFileClose(hFile);
bError := TRUE;
ELSE
iStep := 3;
END_IF
3:
pRes:=SysFileFlush(hFile); //缓存内容写入文件
IF (pRes=0) THEN
iStep := 4;
ELSE
SysFileClose(hFile);
bError := TRUE;
END_IF
4:
pRes:=SysFileClose(hFile); //关闭文件
IF pRes=0 THEN
Done := TRUE;
iStep := 0;
ELSE
bError := TRUE;
END_IF
END_CASE
//错误检查
IF bError THEN
iStep := 0;
ErrorCode := 1;
END_IF
注意:SysFile库的文件读写操作是不能被其它周期任务中断的。当需要读写的文件较大时,需要的时间会比较长。这时候需要把运行读写程序的任务周期调长,保证读写操作能够顺利完成。如果任务时间不够,可能会出现文件没有读完或者写完的情况。
四、结论
SysFile库实际上属于运行系统的文件操作函数,不管是操作方式还是参数定义都与C语言的对应函数类似,对C语言比较熟悉的朋友应该很容易上手。另外需要注意的是底层操作函数与平台相关性较大,比如读写时间与所使用的的控制器平台关系很大,最好是在自己使用的平台上做一些读写测试后设置合理的任务周期,避免出现文件读写不完整问题。
关于SysFile库读写大文件的问题,还有一种思路是把以上代码封装成功能块,在读或者写过程中把大文件拆分成尺寸较小的块,通过分步多次读写,每次进入读写流程时读或者写一块,直至所有内容读写完成。当然这个流程会复杂一些,嫌麻烦的还是直接用CAA File库来实现吧~~~^-^。
————————————————
版权声明:本文为CSDN博主「--莫名--」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/halps/article/details/128974489
页:
[1]