功能块的实现代码如下
FUNCTION_BLOCK ReadFile2Base64
VAR_INPUT
xRead : BOOL:=FALSE;
szFileName : STRING(128) := 'Application/myFile.txt';//文件的路径和名称,根据你的个人情况进行修改
END_VAR
VAR_OUTPUT
base64String : STRING(27962026);//存放读取文件的内容 最大支持20M的文件
done : BOOL; //读取完成
END_VAR
VAR
hFile : SysTypes.RTS_IEC_HANDLE;//句柄
iecResult : SysTypes.RTS_IEC_RESULT;//记录函数执行的结果
udiRead : __XWORD;
udiSize : LWORD; //用来存储文件的大小
byteBuffer : ARRAY[0..20971520] OF BYTE; //最大支持20M的文件
rTrg : R_TRIG;
byError : BYTE;
StringToConvert : PT_SIZE;
EncodedString : PT_SIZE;
testText : STRING;
blockCount : ULINT;
index : ULINT;
offset : ULINT;
totalSize : ULINT;
udiWrite : __XWORD;
myCount : INT ;
readCount : INT;
END_VAR
--------------------------------------------
rTrg(CLK:= xRead);
IF rTrg.Q THEN
readCount := readCount + 1;
done := FALSE;
//打开指定路径的文件,并将文件句柄保存在hFile中,同时通过iecResult记录函数执行的结果
//hFile存储打开文件后返回的文件句柄,如果打开文件成功,hFile获得有效的文件句柄,否则返回无效的句柄值。
//文件句柄是操作系统为文件分配的唯一标识符,之后的文件操作需要使用这个句柄来标识文件
//am:指定文件的打开方式,SYSFILE.AM_READ,以只读的方式打开文件
//pResult:指针参数,用于接收函数执行的结果
hFile := SysFileOpen(szFile:=szFileName, am:=SYSFILE.AM_READ , pResult:=ADR(iecResult));
IF hFile <> RTS_INVALID_HANDLE THEN //hFile不是无效句柄,说明成功打开文件
//SysFileGetSize函数获取文件的大小,并将结果存储在udisize变量中
udisize := SysFileGetSize(szFileName:=szFileName, pResult:=ADR(iecResult));
//将文件中的内容读取到指定的缓冲区中。成功读取时,将返回udiRead表示实际读取的字节数,失败时将返回错误代码,并将错误状态存储在iecResult变量中。
//pbyBuffer是用于存储读取内容的缓冲区
//ulSize是要读取的字节数
//pResult: 这是指向结果的指针,用于接收操作的结果状态。
udiRead := SysFileread(hFile:=hFile, pbyBuffer:=ADR(byteBuffer), ulSize:=udiSize, pResult:=ADR(iecResult));
//关闭文件
iecResult := SysFileClose(hFile:=hFile);
// 进行base64编码
// 一次只能加密22800字节, 所以得分多次加密
blockCount := udisize / TextBlockSize.iBlockSize;
IF (udisize MOD TextBlockSize.iBlockSize) <> 0 THEN
blockCount := blockCount + 1;
END_IF
offset := 0;
byError := 0;
myCount := 0;
IF blockCount > 1 THEN
FOR index := 1 TO blockCount BY 1 DO
myCount := myCount + 1;
StringToConvert.pString := ADR(byteBuffer) + LINT_TO_DWORD((index - 1) * TextBlockSize.iBlockSize);
IF index < blockCount THEN
StringToConvert.uiSize := TextBlockSize.iBlockSize;
EncodedString := Base64(TextToEncode := StringToConvert, isLastBlock := FALSE, pbyError := ADR(byError));
ELSE
StringToConvert.uiSize := LINT_TO_UINT(udisize - ( blockCount - 1) * TextBlockSize.iBlockSize);
EncodedString := Base64(TextToEncode := StringToConvert, isLastBlock := TRUE, pbyError := ADR(byError));
END_IF
strcpyA(ADR(base64String) + offset, 6553500, EncodedString.pString);
offset := offset + EncodedString.uiSize - 1; // 减去0字符, 这里减1暂时还是不太明白,但是-1就正确了
END_FOR
END_IF
totalSize := offset;
// 把结果保存一下测试的
(*
hFile := SysFileOpen(szFile:='Application/zyTemp.txt', am:=SYSFILE.AM_APPEND_PLUS , pResult:=ADR(iecResult));
IF hFile <> RTS_INVALID_HANDLE THEN
//sysfileSetpos:用于设置文件指针的位置,即将文件指针定位到指定的偏移量位置。
//ulOffset: 输入参数,它表示要设置文件指针的偏移量位置。即用于表示文件指针要定位的起始位置。
sysfileSetpos(hFile:=hFile,ulOffset:= 0);
//SysFileWrite函数:将数据从指定的缓冲区写入到文件中,并返回写入的字节数。这个值会被赋给udiWrite
//pbyBuffer: 输入参数,它是指向要写入文件的数据缓冲区的指针。
//ulSize: 输入参数,表示要写入的数据的大小(字节数)。
//pResult: 输出参数,用于存储函数执行的结果。
udiWrite := SysFileWrite(hFile:=hFile, pbyBuffer:=ADR(base64String), ulSize:=totalSize, pResult:=ADR(iecResult));
//关闭文件
iecResult := SysFileClose(hFile:=hFile);
END_IF
*)
END_IF
done := TRUE;
END_IF
调用时
PROGRAM READ_PRG
VAR
readFile : ReadFile2Base64;
testStr : STRING(255) := '1231231231231base';;
beginRead : BOOL := FALSE;
END_VAR
------------------------------------------
readFile(xRead:= beginRead, szFileName:= 'Application/robotArm.glb' , done=> );
参考:
【Codesys-读写文件】