文件传输 (DarraUa_File_*)
概述
OPC UA Part 5 §10 FileType (i=11575) 暴露 6 个 Method。SDK 封装为一组 DarraUa_File_* C API。
API
| 函数 | 类别 | 读写 | 说明 |
|---|---|---|---|
| DarraUa_File_New(ua, file_nid, &out_handle) | 构造 | — | 绑定 |
| DarraUa_File_Free(handle) | 释放 | — | 析构 (自动 Close) |
| DarraUa_File_GetSize(h, &out_size) | 属性 | 读 | uint64 |
| DarraUa_File_GetWritable(h, &out_bool) | 属性 | 读 | bool |
| DarraUa_File_GetUserWritable(h, &out_bool) | 属性 | 读 | bool |
| DarraUa_File_GetOpenCount(h, &out_count) | 属性 | 读 | uint16 |
| DarraUa_File_Open(h, mode, &out_handle_id) | 方法 | 写 | 打开 |
| DarraUa_File_Read(h, length, &out_bytes, &out_n) | 方法 | 读 | 读 |
| DarraUa_File_Write(h, bytes, n) | 方法 | 写 | 写 |
| DarraUa_File_Close(h) | 方法 | 写 | 关闭 |
| DarraUa_File_DownloadTo(h, local_path, progress_cb, ctx) | 高层 | 读 | 一键下载 |
| DarraUa_File_UploadFrom(h, local_path, progress_cb, ctx) | 高层 | 写 | 一键上传 |
相关结构:
typedef enum {
FILE_READ = 0x01, // 读
FILE_WRITE = 0x02, // 写
FILE_ERASE_EXISTING = 0x04, // 清空
FILE_APPEND = 0x08 // 追加
} DarraUa_FileOpenMode;
进度回调签名: void cb(uint64_t done, uint64_t total, void* ctx)。
代码示例
#include <opcua.h>
void on_progress(uint64_t done, uint64_t total, void* ctx) {
printf("\r%llu%% (%llu/%llu)",
(unsigned long long)(done * 100 / total),
(unsigned long long)done,
(unsigned long long)total);
}
int main() {
DarraUa_Session* ua;
DarraUa_Session_New("opc.tcp://device:4840", &ua);
DarraUa_Session_Connect(ua);
// 1) 一键下载固件
DarraUa_File* file = NULL;
DarraUa_File_New(ua, "ns=2;s=Firmware.Image", &file);
uint64_t size;
DarraUa_File_GetSize(file, &size);
printf("Size = %llu\n", (unsigned long long)size);
DarraUa_StatusCode rc = DarraUa_File_DownloadTo(file,
"C:\\dl\\firmware.bin", on_progress, NULL);
if (rc != UA_GOOD) printf("\n下载失败 0x%08X\n", rc);
DarraUa_File_Free(file);
// 2) 手动流式读
DarraUa_File* f3 = NULL;
DarraUa_File_New(ua, "ns=2;s=Logs.Current", &f3);
uint32_t handle_id;
DarraUa_File_Open(f3, FILE_READ, &handle_id);
while (1) {
uint8_t* chunk = NULL;
size_t n = 0;
DarraUa_StatusCode st = DarraUa_File_Read(f3, 4096, &chunk, &n);
if (st != UA_GOOD || n == 0) {
DarraUa_FreeBytes(chunk);
break;
}
process_chunk(chunk, n);
DarraUa_FreeBytes(chunk);
}
DarraUa_File_Close(f3);
DarraUa_File_Free(f3);
DarraUa_Session_Free(ua);
return 0;
}
实现说明
- 块大小默认 4 KB
- ByteString 走
uint8_t* + size_t一对参数, 调用方负责DarraUa_FreeBytes释放 - Method NodeId 解析: 优先 TranslateBrowsePaths, fallback 类级 NodeId
最佳实践
- 始终在每个分支调 Free, C 没有 RAII
- 大文件分段重试
- 不要并发同一 file_handle
跨语言对照
| C# | Python | Java | C++ | Rust | C |
|---|---|---|---|---|---|
| OpcUaFile | OpcUaFile | OpcUaFile | OpcUaFile | OpcUaFile | DarraUa_File_* |
| DownloadTo | download_to | downloadTo | DownloadTo | download_to | DarraUa_File_DownloadTo |
| UploadFrom | upload_from | uploadFrom | UploadFrom | upload_from | DarraUa_File_UploadFrom |