跳到主要内容

文件传输 (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

下一步​