文件传输 (OpcUaFile)
概述
OPC UA Part 5 §10 FileType (i=11575) 暴露 6 个 Method。SDK 封装为 OpcUaFile 类。
API
| 方法 / 属性 | 类别 | 读写 | 说明 |
|---|---|---|---|
| OpcUaFile(ua, file_node_id) | 构造 | — | 绑定 |
| file.Size() | 属性 | 读 | 文件大小 (uint64_t) |
| file.Writable() | 属性 | 读 | 是否可写 |
| file.UserWritable() | 属性 | 读 | 当前用户可写 |
| file.OpenCount() | 属性 | 读 | 当前打开数 |
| file.Open(mode) | 方法 | 写 | 打开 |
| file.Read(length) | 方法 | 读 | 读 N 字节 |
| file.Write(bytes) | 方法 | 写 | 写 |
| file.Close() | 方法 | 写 | 关闭 (析构自动调) |
| file.DownloadTo(local_path, progress) | 高层 | 读 | 一键下载 |
| file.UploadFrom(local_path, progress) | 高层 | 写 | 一键上传 |
相关结构 (FileOpenMode 标志位):
- Read (0x01) — 读
- Write (0x02) — 写
- EraseExisting (0x04) — 清空
- Append (0x08) — 追加
代码示例
#include <darra/opcua.h>
using namespace darra::opcua;
DarraOpcUa ua("opc.tcp://device:4840");
ua.Connect();
// 1) 一键下载固件 (RAII 管理 close)
{
OpcUaFile file(ua, "ns=2;s=Firmware.Image");
std::cout << "Size = " << file.Size() << "\n";
auto progress = [](uint64_t done, uint64_t total) {
std::cout << "\r" << (done * 100 / total) << "% ("
<< done << "/" << total << ")" << std::flush;
};
auto rc = file.DownloadTo("C:/dl/firmware.bin", progress);
if (rc != StatusCode::Good)
std::cerr << "\n下载失败: " << rc << "\n";
}
// 2) 一键上传配方
{
OpcUaFile f2(ua, "ns=2;s=Recipe.Current");
auto rc = f2.UploadFrom("C:/recipes/new.csv");
}
// 3) 手动流式读
{
OpcUaFile f3(ua, "ns=2;s=Logs.Current");
f3.Open(FileOpenMode::Read);
while (true) {
auto [st, chunk] = f3.Read(4096);
if (st != StatusCode::Good || chunk.empty()) break;
ProcessChunk(chunk);
}
f3.Close();
}
实现说明
- 块大小默认 4 KB
- ByteString 走
std::vector<uint8_t> - Method NodeId 解析: 优先 TranslateBrowsePaths, fallback 类级 NodeId
最佳实践
- 用 RAII 管理生命周期, 析构自动 Close
- 大文件分段重试
- 不要并发同一 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 |