You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TwinCAT如何获取文件大小?动态内存分配需求求助

在Beckhoff PLC中获取CSV文件大小的几种实现方法

方法1:使用标准文件操作功能块组合(推荐)

不用依赖系统API,纯PLC标准功能块就能实现:

  • 用FB_Open以**只读模式(MODE_READ)**打开目标CSV文件
  • 调用FB_Seek,将文件指针移动到文件末尾(iMode设为SEEK_END,对应数值2,iOffset设0)
  • 调用FB_Tell获取当前指针位置,这个值就是文件的总字节数
  • 完成后记得用FB_Close关闭文件

示例ST代码:

VAR
    hFile: DINT;
    bOpenSuccess: BOOL;
    bSeekSuccess: BOOL;
    bGetSizeSuccess: BOOL;
    nFileSize: DINT;
    fbOpen: FB_Open;
    fbSeek: FB_Seek;
    fbTell: FB_Tell;
    fbClose: FB_Close;
END_VAR

// 打开文件(只读模式)
fbOpen(
    sFileName := 'C:\Data\target.csv',
    iMode := MODE_READ,
    xExecute := TRUE,
    xDone => bOpenSuccess,
    hFile => hFile,
    xError => 
);

IF bOpenSuccess THEN
    // 将指针移至文件末尾
    fbSeek(
        hFile := hFile,
        iMode := 2, // SEEK_END
        iOffset := 0,
        xExecute := TRUE,
        xDone => bSeekSuccess,
        xError => 
    );

    IF bSeekSuccess THEN
        // 获取文件大小
        fbTell(
            hFile := hFile,
            xExecute := TRUE,
            xDone => bGetSizeSuccess,
            iPosition => nFileSize,
            xError => 
        );

        IF bGetSizeSuccess THEN
            // nFileSize即为文件字节数,可用于动态内存分配
            // 关闭文件
            fbClose(
                hFile := hFile,
                xExecute := TRUE
            );
        END_IF;
    END_IF;
END_IF;

方法2:通过ADS调用Windows CE系统API

如果PLC是Beckhoff CX系列(基于Windows CE),可以通过ADS直接调用系统API获取文件信息,推荐用FindFirstFileW函数(无需打开文件即可获取大小):

  • 构造AMS地址指向本地设备(或远程目标设备)
  • 用FB_AmsCallFunction调用kernel32.dll中的FindFirstFileW,传入文件路径(宽字符格式)
  • 解析返回的WIN32_FIND_DATAW结构体,其中nFileSizeLow和nFileSizeHigh组合为文件总大小
  • 调用FindClose关闭查找句柄

示例ST代码片段:

VAR
    stLocalAmsAddr: AMS_ADDR;
    hFindHandle: HANDLE;
    nCallResult: DINT;
    sTargetPath: STRING(256) := 'C:\Data\target.csv';
    // 定义WIN32_FIND_DATAW结构体(宽字符版)
    stFileInfo: STRUCT
        dwFileAttributes: DWORD;
        ftCreationTime: FILETIME;
        ftLastAccessTime: FILETIME;
        ftLastWriteTime: FILETIME;
        nFileSizeHigh: DWORD;
        nFileSizeLow: DWORD;
        dwReserved0: DWORD;
        dwReserved1: DWORD;
        cFileName: ARRAY[0..259] OF WCHAR;
        cAlternateFileName: ARRAY[0..13] OF WCHAR;
    END_STRUCT;
    fbAmsCall: FB_AmsCallFunction;
    fbCloseFind: FB_AmsCallFunction;
END_VAR

// 获取本地AMS地址
stLocalAmsAddr := AmsGetLocalAddress();

// 调用FindFirstFileW获取文件信息
fbAmsCall(
    AmsAddr := stLocalAmsAddr,
    nPort := 851, // Windows CE的默认ADS端口
    sDllName := 'kernel32.dll',
    sFuncName := 'FindFirstFileW',
    pInput := ADR(sTargetPath),
    cbInput := LEN(sTargetPath) * 2, // 宽字符占2字节/字符
    pOutput := ADR(stFileInfo),
    cbOutput := SIZEOF(stFileInfo),
    xExecute := TRUE,
    nResult => hFindHandle,
    xDone => ,
    xError => 
);

IF fbAmsCall.xDone AND (hFindHandle <> INVALID_HANDLE_VALUE) THEN
    // 计算文件大小:32位场景直接用nFileSizeLow,超4GB则合并高低位
    nFileSize := stFileInfo.nFileSizeLow;
    // 64位大小计算:nFileSize64 := TO_LWORD(stFileInfo.nFileSizeHigh) * 4294967296 + stFileInfo.nFileSizeLow;

    // 关闭查找句柄
    fbCloseFind(
        AmsAddr := stLocalAmsAddr,
        nPort := 851,
        sDllName := 'kernel32.dll',
        sFuncName := 'FindClose',
        pInput := ADR(hFindHandle),
        cbInput := SIZEOF(hFindHandle),
        xExecute := TRUE
    );
END_IF;

方法3:预记录文件大小(适合自定义生成的CSV)

如果CSV文件是由你的PLC程序生成的,可以在每次写入完成后,将当前文件大小写入一个配套的小配置文件(比如csv_size.dat):

  • 写入CSV后,用方法1获取当前文件大小
  • 将大小值写入同目录的配置文件
  • 读取CSV前,先读取该配置文件的数值,直接用于内存分配

这种方法无需复杂操作,可靠性高,适合可控的文件生成场景。


内容的提问来源于stack exchange,提问作者Mirek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:05:36