跳到主要内容

文件传输 (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#PythonJavaC++RustC
OpcUaFileOpcUaFileOpcUaFileOpcUaFileOpcUaFileDarraUa_File_*
DownloadTodownload_todownloadToDownloadTodownload_toDarraUa_File_DownloadTo

下一步