Common tasks
Recipes for the things you actually do with storage. Each works on every
service. They assume an op built as in
Getting started.
A few conventions used throughout:
- Paths are relative to the operator's root; a trailing
/means a directory (logs/app/is a directory,logs/appis a file). Readreturnsbyte[];Writetakesbyte[].- Every method has an
…Asynccounterpart that returns aTaskand accepts aCancellationToken. The recipes below show the sync form; addAsync/awaitfor the async API. - Option types live in
OpenDAL.Options.
Read a whole file
using System.Text;
byte[] bytes = op.Read("path/to/file");
string text = Encoding.UTF8.GetString(bytes);
Read part of a file
Pass a ReadOptions with an offset and length:
using OpenDAL.Options;
byte[] head = op.Read("path/to/file", new ReadOptions { Offset = 0, Length = 1024 });
Write a whole file
using System.Text;
op.Write("path/to/file", Encoding.UTF8.GetBytes("Hello, World!"));
WriteOptions carry content headers, conditions, append mode, and concurrency:
using OpenDAL.Options;
await op.WriteAsync("docs/readme.txt", content, new WriteOptions
{
ContentType = "text/plain",
CacheControl = "no-cache",
IfNotExists = true,
});
Stream a large file
Don't buffer gigabytes in memory — open a Stream and read in chunks.
OpenReadStream returns an OperatorInputStream:
using var reader = op.OpenReadStream("big.bin");
using var ms = new MemoryStream();
reader.CopyTo(ms);
Stream a large upload
OpenWriteStream returns an OperatorOutputStream. Write incrementally, then
dispose to flush and close the native resources deterministically:
using System.Text;
await using (var writer = op.OpenWriteStream("big.bin"))
{
var chunk = Encoding.UTF8.GetBytes("stream-data");
await writer.WriteAsync(chunk, 0, chunk.Length);
await writer.FlushAsync();
}
OpenWriteStream also accepts a bufferSize argument that controls how much is
buffered before flushing to the backend.
Check existence and metadata
var meta = op.Stat("path/to/file");
Console.WriteLine($"{meta.ContentLength} bytes, dir = {meta.IsDir}");
A missing path throws OpenDALException with ErrorCode.NotFound; see
error handling.
List a directory
List returns the entries under a path:
foreach (var entry in op.List("dir/"))
{
Console.WriteLine($"{entry.Path} ({entry.Metadata.Mode})");
}
Walk a tree recursively
using OpenDAL.Options;
var entries = op.List("dir/", new ListOptions { Recursive = true });
Delete a file or a whole tree
op.Delete("path/to/file"); // single path
op.RemoveAll("dir/"); // a path and everything under it
Create a directory
op.CreateDir("path/to/dir/"); // the trailing slash is required
Copy and rename
op.Copy("from.txt", "to.txt");
op.Rename("old.txt", "new.txt");
Both operate within a single operator and require a service that supports them; see capability checks.
Generate a presigned URL
Hand a time-limited URL to a third party so they can access an object without your credentials. Presigning is part of the async API:
var request = await op.PresignReadAsync("data/file.txt", TimeSpan.FromMinutes(10));
Console.WriteLine(request.Method);
Console.WriteLine(request.Uri);
foreach (var header in request.Headers)
{
Console.WriteLine($"{header.Key}: {header.Value}");
}
The available presign methods are PresignReadAsync, PresignWriteAsync,
PresignStatAsync, and PresignDeleteAsync.