跳到主要内容

文件传输 (OpcUaFile)

概述

OPC UA Part 5 §10 FileType (i=11575) 暴露 6 个 Method。SDK 封装为 OpcUaFile 类, 适用固件升级 / 配方传输。

API

方法 / 属性类别读写说明
new OpcUaFile(ua, fileNodeId)构造绑定到 FileType 实例
file.getSize()属性文件大小 (long)
file.isWritable()属性是否可写
file.isUserWritable()属性当前用户可写
file.getOpenCount()属性当前打开数
file.open(mode)方法打开
file.read(length)方法读 N 字节
file.write(bytes)方法
file.close()方法关闭
file.downloadTo(localPath, progress)高层一键下载
file.uploadFrom(localPath, progress)高层一键上传

相关结构:

public enum FileOpenMode {
READ (0x01), // 读
WRITE (0x02), // 写
ERASE_EXISTING (0x04), // 清空
APPEND (0x08); // 追加

public final int value;
FileOpenMode(int v) { this.value = v; }
}

代码示例

import com.darra.opcua.*;
import java.util.EnumSet;
import java.util.function.BiConsumer;

try (DarraOpcUa ua = new DarraOpcUa("opc.tcp://device:4840")) {
ua.connect();

// 1) 一键下载固件
try (OpcUaFile file = new OpcUaFile(ua, "ns=2;s=Firmware.Image")) {
System.out.println("Size = " + file.getSize());

BiConsumer<Long, Long> progress = (done, total) ->
System.out.printf("\r%d%% (%d/%d)", done * 100 / total, done, total);

StatusCode rc = file.downloadTo("C:/dl/firmware.bin", progress);
if (rc != StatusCode.Good)
System.out.println("\n下载失败: " + rc);
}

// 2) 一键上传配方
try (OpcUaFile f2 = new OpcUaFile(ua, "ns=2;s=Recipe.Current")) {
f2.uploadFrom("C:/recipes/new.csv", null);
}

// 3) 手动流式读
try (OpcUaFile f3 = new OpcUaFile(ua, "ns=2;s=Logs.Current")) {
f3.open(EnumSet.of(FileOpenMode.READ));
while (true) {
ReadChunkResult r = f3.read(4096);
if (r.status != StatusCode.Good || r.bytes == null || r.bytes.length == 0) break;
processChunk(r.bytes);
}
f3.close();
}
}

实现说明

  • 块大小默认 4 KB
  • ByteString 走 ISO-8859-1 字符串桥接, 无损保留 0x00-0xFF
  • Method NodeId 解析: 优先 TranslateBrowsePaths, fallback 类级 NodeId

最佳实践

  • 始终用 try-with-resources, 漏 close 会泄漏服务端句柄
  • 大文件分段重试
  • 不要并发同一 fileHandle

跨语言对照

C#PythonJavaC++RustC
OpcUaFileOpcUaFileOpcUaFileOpcUaFileOpcUaFileDarraUa_File_*
DownloadTodownload_todownloadToDownloadTodownload_toDarraUa_File_DownloadTo

下一步