文件传输 (OpcUaFile)
概述
OPC UA Part 5 §10 FileType (i=11575) 暴露 6 个 Method。SDK 封装为 OpcUaFile 类型, RAII 自动管理 close。
API
| 方法 / 字段 | 类别 | 读写 | 说明 |
|---|---|---|---|
| OpcUaFile::new(ua, file_node_id) | 构造 | — | 绑定 |
| file.size() | 方法 | 读 | u64 |
| file.writable() | 方法 | 读 | bool |
| file.user_writable() | 方法 | 读 | bool |
| file.open_count() | 方法 | 读 | u16 |
| file.open(mode) | 方法 | 写 | 打开 |
| file.read(length) | 方法 | 读 | Result<Vec<u8>> |
| file.write(bytes) | 方法 | 写 | 写 |
| file.close() | 方法 | 写 | 关闭 (Drop 自动) |
| file.download_to(local_path, progress) | 高层 | 读 | 一键下载 |
| file.upload_from(local_path, progress) | 高层 | 写 | 一键上传 |
相关结构:
pub struct FileOpenMode;
impl FileOpenMode {
pub const READ: u8 = 0x01; // 读
pub const WRITE: u8 = 0x02; // 写
pub const ERASE_EXISTING: u8 = 0x04; // 清空
pub const APPEND: u8 = 0x08; // 追加
}
代码示例
use opcua::{DarraOpcUa, OpcUaFile, FileOpenMode, StatusCode};
let ua = DarraOpcUa::new("opc.tcp://device:4840")?;
ua.connect()?;
// 1) 一键下载固件 (Drop 自动 close)
{
let file = OpcUaFile::new(&ua, "ns=2;s=Firmware.Image")?;
println!("Size = {} bytes", file.size()?);
let rc = file.download_to(r"C:\dl\firmware.bin", |done, total| {
print!("\r{}% ({}/{})", done * 100 / total, done, total);
})?;
if rc != StatusCode::Good { eprintln!("\n下载失败: {:?}", rc); }
}
// 2) 一键上传配方
{
let f2 = OpcUaFile::new(&ua, "ns=2;s=Recipe.Current")?;
f2.upload_from(r"C:\recipes\new.csv", |_, _| {})?;
}
// 3) 手动流式读
{
let f3 = OpcUaFile::new(&ua, "ns=2;s=Logs.Current")?;
f3.open(FileOpenMode::READ)?;
loop {
let chunk = f3.read(4096)?;
if chunk.is_empty() { break; }
process_chunk(&chunk);
}
// f3 离开作用域时 Drop 自动 close
}
实现说明
- 块大小默认 4 KB
- ByteString 走
Vec<u8> - Method NodeId 解析: 优先 TranslateBrowsePaths, fallback 类级 NodeId
最佳实践
- 用 RAII 管理生命周期 (Drop 自动 close)
- 大文件分段重试
- 不要并发同一 file_handle (Rust 借用检查会拦)
跨语言对照
| C# | Python | Java | C++ | Rust | C |
|---|---|---|---|---|---|
| OpcUaFile | OpcUaFile | OpcUaFile | OpcUaFile | OpcUaFile | DarraUa_File_* |
| DownloadTo | download_to | downloadTo | DownloadTo | download_to | DarraUa_File_DownloadTo |