The specialized EasyUAFileTransferClient object allows you to make OPC UA file transfer operations easily, without having to deal with details of the corresponding OPC UA service or method calls. You do not have study the OPC UA specifications and write low-level code to make each method call; all this knowledge is already encapsulated in the specialized client object for you. For example, you can directly call methods such as OpenFile or ReadFile, without having to know the method Ids and how to put together the array of method arguments and dissect the result.
This article describes API levels 2 and 2+ for OPC UA File Transfer (the EasyUAFileTransferClient Class together with the extension methods defined in the IEasyUAFileTransferExtension Class). For an overview of API levels, see OPC UA File Transfer.
The features discussed here, or some of them, may not be available in all editions of the product. Check the
Product Editions page for differences between the editions. The trial license has all features enabled (and is limited in period for which it provides valid data), but licenses for specific commercial editions may have functionality limitations.
This functionality is not available under (or the text does not apply to) COM development platform.
Operations overview
Methods (the basic set, i.e. API level 2, IEasyUAFileTransferClient Interface) are available to:
- Obtain information about specific files
- Create, open and close files
- Read data from and write data to files
- Get and set position in the file
- Delete files
- Create and delete directories
- Move or copy files and directories
- List contents of directories
- Finding files, directories, and finding a parent directory
- Finding a file system on a specified OPC UA object
- Determining whether the specified node represents a file or directory
Extensions methods (i.e. API level 2+, in IEasyUAFileTransferExtension Class) are used to expose more overloads (different structure of arguments) to the above methods, and to provide more complex functionality. Also, the extension methods provide distinction between files and directories where the OPC UA File Transfer does not: For example, if you specifically want to move a file, you need to be sure that you do not move a directory that happens to have the same name. The "raw" OPC UA File Transfer do not make this distinction. Other extension methods are available to:
- Find a directory given the named path, or create all directories on the path
- Find a root directory
- Find a (reverse) path to the root directory
You may want to look at OPC UA File Transfers internals in order to understand a bit of what is happening "under the hood".
Error model
The error model of OPC UA File Transfer Client object is as described in Error Model in imperative programming. In short, leaving aside usage errors (incorrect arguments or invalid operations, which can be prevented and do not appear in correctly written code), most methods throw only UAException. Methods that return OperationResult (or an array of them) do not indicate errors by throwing exceptions at all, but instead, you can inspect the Exception Property after the method has returned.
File handles
An OPC UA file handle encapsulates an access request to the OPC UA file. It is represented by the UAFileHandle Class, and returned by some of the methods, such as CreateFile Method or OpenFile Method. The handle is then subsequently used in methods like ReadFile or WriteFile. When you are finished with accessing the OPC UA file, your code should call the CloseFile Method with the handle, and also dispose of the OPC file handle object using its IDisposable.Dispose Method (this can be achieved in C# or VB.NET by the means of the "using" statement).
Dealing with OPC UA file handles is somewhat cumbersome, and you may want to consider using OPC UA File Streams for accessing the file data instead.
Reading and writing file data
In order to read from and/or write to a file:
- Open or create the file and obtain the file handle: The OpenFile Method, CreateFile Method, their extension methods with a different structure of arguments, or the CreateAndOpenFile Method or CreateOrOpenFile Method extension methods.
- If needed, use the file position to navigate inside the file: The GetFilePosition Method, the SetFilePosition Method.
- Perform the actual reads and writes: ReadFile Method, WriteFile Method.
- When finished, close the file handle and dispose of the file handle object: CloseFile Method, IDisposable.Dispose Method.
Note that when using methods from API level 2 and 2+, QuickOPC automatically provides read/write chunking, but no file data buffering (see OPC UA File Transfer internals for more information). Use OPC UA File Streams if file data buffering is needed.
Reading
The example below shows how to read different sections from an OPC UA file, using the file transfer client.
If you want to read the whole contents of a file at once, you can use extension methods described in OPC UA File Streams.
Writing
The example below shows how to write data into a section of an OPC UA file, using the file transfer client.
If you want to write the whole contents of a file at once, you can use extension methods described in OPC UA File Streams.
Creating, deleting, copying and moving files and directories
You will find following (and more) functionality in this group of methods:
- Create a directory: The CreateDirectory Method.
- Delete files and/or directories: The general Delete Method, and the more specific or qualified extension methods: DeleteDirectory Method, DeleteDirectoryIfExists Method, DeleteFile Method, DeleteFileIfExists Method, DeleteIfExists Method.
- Copy or move files and/or directories: The MoveOrCopy Method, and the more specific extension methods: Copy Method, CopyFile Method, Move Method, MoveDirectory Method, MoveFile Method, MoveOrCopy Method, MoveOrCopyDirectory Method, MoveOrCopyFile Method.
- Rename files and/or directories: The Rename Method (extension).
- Find a directory if it exists; create the directory (also optionally together with the directories on the path), if not found: FindOrCreateDirectory Method, FindOrCreateDirectory Method (extension).
The FindXXXX methods (except for FindOrCreateXXXX methods) return a null reference when the specified object does not exist. The GetXXXX methods return an error (throw an exception) if the specified object does not exist.
The example below shows how to create and delete OPC UA directories, using the file transfer client.
// Shows how to create and delete OPC UA directories, using the file transfer client.
// Note: Consider using a higher-level abstraction, OPC UA file provider, instead.
using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.Extensions;
using OpcLabs.EasyOpc.UA.FileTransfer;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples.FileTransfer._EasyUAFileTransferClient
{
class CreateDirectoryAndDelete
{
public static void Main1()
{
// Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
var endpointDescriptor = new UAEndpointDescriptor("opc.tcp://localhost:48030")
.WithUserNameIdentity("john", "master");
// An object that aggregates an OPC UA file system.
UANodeDescriptor objectDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files";
// Create a random number generator - will be used for file/directory names.
var random = new Random();
// Instantiate the file transfer client object
var fileTransferClient = new EasyUAFileTransferClient();
// Create two directories, and one nested directory, and delete the first one.
try
{
// The file system node is a root directory of the file system.
Console.WriteLine("Getting file system...");
UANodeDescriptor fileSystemNodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor);
string directoryName1 = "MyDirectory1-" + random.Next();
Console.WriteLine($"Creating first directory, '{directoryName1}'...");
UANodeId directoryNodeId1 = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1);
Console.WriteLine($"Node Id of the first directory: {directoryNodeId1}");
string directoryName2 = "MyDirectory2-" + random.Next();
Console.WriteLine($"Creating second directory, '{directoryName2}'...");
UANodeId directoryNodeId2 = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName2);
Console.WriteLine($"Node Id of the second directory: {directoryNodeId2}");
string nestedDirectoryName = "MyDirectory3-" + random.Next();
Console.WriteLine($"Creating nested directory, '{nestedDirectoryName}'...");
// Note how directoryNodeId2 (a parent directory) is passed as the 2nd argument to the CreateDirectory method.
UANodeId nestedDirectoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor, directoryNodeId2, nestedDirectoryName);
Console.WriteLine($"Node Id of the nested directory: {nestedDirectoryNodeId}");
// At this moment, the directory structure we have created looks like this:
// * MyDirectory1
// * MyDirectory2
// * * MyDirectory3
Console.WriteLine("Deleting the first directory...");
fileTransferClient.DeleteDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
return;
}
Console.WriteLine("Finished...");
}
}
}
# Shows how to create and delete OPC UA directories, using the file transfer client.
# Note: Consider using a higher-level abstraction, OPC UA file provider, instead.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import random
# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Extensions import *
from OpcLabs.EasyOpc.UA.FileTransfer import *
from OpcLabs.EasyOpc.UA.OperationModel import *
# Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe).
endpointDescriptor = UAEndpointDescriptor('opc.tcp://localhost:48030')
endpointDescriptor = UAEndpointDescriptorExtension.WithUserNameIdentity(endpointDescriptor,'john', 'master')
# An object that aggregates an OPC UA file system.
objectDescriptor = UANodeDescriptor('nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files')
# Create a random number generator - will be used for file/directory names.
random = random.Random()
# Instantiate the file transfer client object.
fileTransferClient = EasyUAFileTransferClient()
# Prevent prompt to trust the server certificate (INSECURE, used just for smooth example flow).
EasyUAClient.SharedParameters.EngineParameters.CertificateAcceptancePolicy.TrustEndpointUrlString(
endpointDescriptor.UrlString)
# Create two directories, and one nested directory, and delete the first one.
try:
# The file system node is a root directory of the file system.
print('Getting file system...')
fileSystemNodeDescriptor = IEasyUAFileTransferExtension.GetFileSystem(fileTransferClient,
endpointDescriptor, objectDescriptor)
directoryName1 = 'MyDirectory1-' + str(random.randint(0, 999_999_999))
print("Creating first directory, '", directoryName1, "'...", sep='')
directoryNodeId1 = fileTransferClient.CreateDirectory(endpointDescriptor,
fileSystemNodeDescriptor,
directoryName1)
print('Node Id of the first directory: ', directoryNodeId1, sep='')
directoryName2 = 'MyDirectory2-' + str(random.randint(0, 999_999_999))
print("Creating second directory, '", directoryName2, "'...", sep='')
directoryNodeId2 = fileTransferClient.CreateDirectory(endpointDescriptor,
fileSystemNodeDescriptor,
directoryName2)
print('Node Id of the second directory: ', directoryNodeId1, sep='')
nestedDirectoryName = 'MyDirectory3-' + str(random.randint(0, 999_999_999))
print("Creating nested directory, '", nestedDirectoryName, "'...", sep='')
# Note how directoryNodeId2 (a parent directory) is passed as the 2nd argument to the CreateDirectory method.
nestedDirectoryNodeId = fileTransferClient.CreateDirectory(endpointDescriptor,
UANodeDescriptor(directoryNodeId2),
nestedDirectoryName)
print('Node Id of the nested directory: ', nestedDirectoryNodeId, sep='')
# At this moment, the directory structure we have created looks like this:
# * MyDirectory1
# * MyDirectory2
# * * MyDirectory3
print('Deleting the first directory...')
IEasyUAFileTransferExtension.DeleteDirectory(fileTransferClient,
endpointDescriptor, fileSystemNodeDescriptor, directoryName1)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
exit()
print()
print('Finished.')
' Shows how to create and delete OPC UA directories, using the file transfer client.
' Note: Consider using a higher-level abstraction, OPC UA file provider, instead.
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.Extensions
Imports OpcLabs.EasyOpc.UA.FileTransfer
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace FileTransfer._EasyUAFileTransferClient
Friend Class CreateDirectoryAndDelete
Public Shared Sub Main1()
' Unified Automation .NET based demo server (UaNETServer/UaServerNET.exe)
Dim endpointDescriptor As UAEndpointDescriptor =
New UAEndpointDescriptor("opc.tcp://localhost:48030") _
.WithUserNameIdentity("john", "master")
' An object that aggregates an OPC UA file system.
Dim objectDescriptor As UANodeDescriptor = "nsu=http://www.unifiedautomation.com/DemoServer/ ;s=Demo.Files"
' Create a random number generator - will be used for file/directory names.
Dim random = New Random
' Instantiate the file transfer client object
Dim fileTransferClient = New EasyUAFileTransferClient
' Create two directories, and one nested directory, and delete the first one.
Try
' The file system node is a root directory of the file system.
Console.WriteLine("Getting file system...")
Dim fileSystemNodeDescriptor As UANodeDescriptor = fileTransferClient.GetFileSystem(endpointDescriptor, objectDescriptor)
Dim directoryName1 As String = "MyDirectory1-" & random.Next()
Console.WriteLine($"Creating first directory, '{directoryName1}'...")
Dim directoryNodeId1 As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1)
Console.WriteLine($"Node Id of the first directory: {directoryNodeId1}")
Dim directoryName2 As String = "MyDirectory2-" & random.Next()
Console.WriteLine($"Creating second directory, '{directoryName2}'...")
Dim directoryNodeId2 As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName2)
Console.WriteLine($"Node Id of the second directory: {directoryNodeId2}")
Dim nestedDirectoryName As String = "MyDirectory3-" & random.Next()
Console.WriteLine($"Creating nested directory, '{nestedDirectoryName}'...")
' Note how directoryNodeId2 (a parent directory) Is passed as the 2nd argument to the CreateDirectory method.
Dim nestedDirectoryNodeId As UANodeId = fileTransferClient.CreateDirectory(endpointDescriptor, directoryNodeId2, nestedDirectoryName)
Console.WriteLine($"Node Id of the nested directory: {nestedDirectoryNodeId}")
' At this moment, the directory structure we have created looks Like this
' * MyDirectory1
' * MyDirectory2
' * * MyDirectory3
Console.WriteLine("Deleting the first directory...")
fileTransferClient.DeleteDirectory(endpointDescriptor, fileSystemNodeDescriptor, directoryName1)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
Console.WriteLine("Finished...")
End Sub
End Class
End Namespace
The example below shows how to copy an OPC UA file, using the file transfer client.
Navigation among files and directories
This group of methods provides following functionality:
- Find or get files and directories by name: The FindFile Method and the FindDirectory Method, and their extension methods with a different structure of arguments, or more functionality: FindFileOrDirectory Method, GetDirectory Method, GetFile Method, GetFileOrDirectory Method.
- Find or get an aggregated file system: The FindFileSystem Method, and its extension method(s) with a different structure of arguments, and the GetFileSystem Method (extension).
- Test whether an OPC UA object aggregates a file system: The HasFileSystem Method (extension).
- Find or get parent directory: The FindParentDirectory Method, the GetParentDirectory Method (extension).
- Test whether a file or directory has a parent directory: The HasParentDirectory Method (extension).
- Find or get the root directory: The FindRootDirectory Method (extension), the GetRootDirectory Method (extension).
- Find the root directory and the path from the root to the given object: The FindRootAndPath Method (extension).
- Test whether a given node is a directory, or a file: The IsDirectory Method, the IsFile Method, the IsFileOrDirectory Method (extension).
- Test whether a given node is a root directory: The IsRootDirectory Method (extension).
Getting information about files and directories
This group of methods provides following (and more) operations:
- Get properties (metadata) of a file or multiple files: the GetMultipleFileProperties Method and its extension method(s) with a different structure of arguments, the GetFileProperties Method (extension).
- Get name of a file or directory (or multiple files or directories), given its node (their nodes): The GetMultipleNames Method, and the related extensions - the GetDirectoryName Method, the GetFileName Method, the GetName Method.
- Obtain names of files or directories under the specified parent directory: The ListFileNames Method, the ListDirectoryNames Method, their extension methods with a different structure of arguments, and the ListFileAndDirectoryNames Method (extension).
- Browse for file and/or directory names together with their node descriptors: The BrowseDirectories Method, the BrowseFiles Method (extension).
- Browse a tree of objects (files, directories) available in the directory: The BrowseTree Method (extension).
The example below shows how to get OPC UA file properties (such as its size or writable status), using the file transfer client.
The example below shows how to browse for OPC UA files, using the file transfer client.
See Also
Examples - OPC UA File Transfer
Knowledge Base