2024-04-24 09:46:03 +00:00
|
|
|
# frostfs-sdk-csharp
|
|
|
|
|
2024-04-24 11:58:22 +00:00
|
|
|
C# implementation of FrostFS SDK.
|
|
|
|
|
2024-05-02 08:18:44 +00:00
|
|
|
## Prerequisites
|
|
|
|
|
|
|
|
### Get the key for your wallet
|
|
|
|
|
|
|
|
1. Get the address
|
|
|
|
```bash
|
|
|
|
cat <path_to_your_wallet> | jq .accounts[0].address | tr -d '"'
|
|
|
|
```
|
|
|
|
|
|
|
|
2. Get the key
|
|
|
|
```bash
|
|
|
|
neo-go wallet export -w <path_to_your_wallet> -d <address_from_p1>
|
|
|
|
```
|
|
|
|
|
2024-05-21 13:14:42 +00:00
|
|
|
## Example usage
|
|
|
|
|
|
|
|
### Container
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
using FrostFS.SDK.ClientV2;
|
|
|
|
using FrostFS.SDK.ModelsV2;
|
|
|
|
using FrostFS.SDK.ModelsV2.Enums;
|
|
|
|
using FrostFS.SDK.ModelsV2.Netmap;
|
|
|
|
|
2024-06-10 08:31:36 +00:00
|
|
|
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
2024-05-21 13:14:42 +00:00
|
|
|
|
|
|
|
// List containers
|
|
|
|
var containersIds = await fsClient.ListContainersAsync();
|
|
|
|
|
|
|
|
// Create container
|
|
|
|
var placementPolicy = new PlacementPolicy(true, new Replica(1));
|
|
|
|
var containerId = await fsClient.CreateContainerAsync(
|
|
|
|
new Container(
|
|
|
|
BasicAcl.PublicRW,
|
|
|
|
placementPolicy
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
// Get container
|
|
|
|
var container = await fsClient.GetContainerAsync(cId);
|
|
|
|
|
|
|
|
// Delete container
|
|
|
|
await fsClient.DeleteContainerAsync(containerId);
|
|
|
|
```
|
|
|
|
|
|
|
|
### Object
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
using FrostFS.SDK.ClientV2;
|
|
|
|
using FrostFS.SDK.ModelsV2;
|
|
|
|
using FrostFS.SDK.ModelsV2.Enums;
|
|
|
|
using FrostFS.SDK.ModelsV2.Netmap;
|
|
|
|
|
2024-06-10 08:31:36 +00:00
|
|
|
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
2024-05-21 13:14:42 +00:00
|
|
|
|
|
|
|
// Search regular objects
|
|
|
|
var objectsIds = await fsClient.SearchObjectAsync(
|
|
|
|
cId,
|
|
|
|
ObjectFilter.RootFilter()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Put object
|
|
|
|
var f = File.OpenRead("cat.jpg");
|
|
|
|
var cat = new ObjectHeader(
|
|
|
|
containerId: cId,
|
|
|
|
type: ObjectType.Regular,
|
|
|
|
new ObjectAttribute("Filename", "cat.jpg")
|
|
|
|
);
|
|
|
|
var oId = await fsClient.PutObjectAsync(cat, f);
|
|
|
|
|
|
|
|
// Get object header
|
|
|
|
var objHeader = await fsClient.GetObjectHeadAsync(cId, oId);
|
|
|
|
|
|
|
|
// Get object
|
|
|
|
var obj = await fsClient.GetObjectAsync(cId, oId);
|
2024-06-10 08:31:36 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
### Custom client cut
|
|
|
|
```csharp
|
|
|
|
|
|
|
|
using FrostFS.SDK.ClientV2;
|
|
|
|
using FrostFS.SDK.ModelsV2;
|
|
|
|
using FrostFS.SDK.ModelsV2.Enums;
|
|
|
|
using FrostFS.SDK.ModelsV2.Netmap;
|
|
|
|
using FrostFS.SDK.ClientV2.Extensions;
|
|
|
|
using FrostFS.SDK.ClientV2.Interfaces;
|
|
|
|
|
|
|
|
var fsClient = Client.GetInstance(<your_key>, <your_host>);
|
|
|
|
|
|
|
|
ContainerId containerId = <containerId>;
|
|
|
|
string fileName = <fileName>;
|
|
|
|
|
|
|
|
await PutObjectClientCut(fsClient, containerId, fileName);
|
|
|
|
|
|
|
|
static async Task<ObjectId?> PutObjectClientCut(IFrostFSClient fsClient, ContainerId containerId, string fileName)
|
|
|
|
{
|
|
|
|
List<ObjectId> sentObjectIds = [];
|
|
|
|
FrostFS.SDK.ModelsV2.Object? currentObject;
|
|
|
|
|
|
|
|
var partSize = 1024 * 1024;
|
|
|
|
var buffer = new byte[partSize];
|
|
|
|
|
|
|
|
var largeObject = new LargeObject(containerId);
|
|
|
|
|
|
|
|
var split = new Split();
|
|
|
|
|
|
|
|
var fileInfo = new FileInfo(fileName);
|
|
|
|
var fullLength = (ulong)fileInfo.Length;
|
|
|
|
var fileNameAttribute = new ObjectAttribute("fileName", fileInfo.Name);
|
2024-06-14 08:58:29 +00:00
|
|
|
|
2024-06-10 08:31:36 +00:00
|
|
|
using var stream = File.OpenRead(fileName);
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
var bytesCount = await stream.ReadAsync(buffer.AsMemory(0, partSize));
|
|
|
|
|
|
|
|
split.Previous = sentObjectIds.LastOrDefault();
|
|
|
|
|
|
|
|
largeObject.AppendBlock(buffer, bytesCount);
|
|
|
|
|
2024-06-14 08:58:29 +00:00
|
|
|
currentObject = new FrostFS.SDK.ModelsV2.Object(containerId, bytesCount < partSize ? buffer.Take(bytesCount).ToArray() : buffer)
|
2024-06-10 08:31:36 +00:00
|
|
|
.AddAttribute(fileNameAttribute)
|
|
|
|
.SetSplit(split);
|
|
|
|
|
|
|
|
if (largeObject.PayloadLength == fullLength)
|
|
|
|
break;
|
|
|
|
|
|
|
|
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
|
|
|
sentObjectIds.Add(objectId);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sentObjectIds.Any())
|
|
|
|
{
|
2024-06-14 08:58:29 +00:00
|
|
|
largeObject.CalculateHash()
|
|
|
|
.AddAttribute(fileNameAttribute);
|
|
|
|
|
|
|
|
currentObject.SetParent(largeObject);
|
|
|
|
|
|
|
|
var objectId = await fsClient.PutSingleObjectAsync(currentObject);
|
|
|
|
sentObjectIds.Add(objectId);
|
2024-06-10 08:31:36 +00:00
|
|
|
|
|
|
|
var linkObject = new LinkObject(containerId, split.SplitId, largeObject)
|
2024-06-14 08:58:29 +00:00
|
|
|
.AddChildren(sentObjectIds)
|
|
|
|
.AddAttribute(fileNameAttribute);
|
2024-06-10 08:31:36 +00:00
|
|
|
|
|
|
|
_ = await fsClient.PutSingleObjectAsync(linkObject);
|
|
|
|
|
|
|
|
return currentObject.GetParentId();
|
|
|
|
}
|
|
|
|
|
|
|
|
return await fsClient.PutSingleObjectAsync(currentObject);
|
|
|
|
}
|
|
|
|
|
2024-05-21 13:14:42 +00:00
|
|
|
```
|