or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-operations.mdindex.mdlayers.mdservices.mdtypes.md

core-operations.mddocs/

0

# Core Operations

1

2

OpenDAL provides a comprehensive set of file and directory operations through both async (`Operator`) and blocking (`BlockingOperator`) interfaces. All operations follow consistent patterns and provide the same functionality across all storage backends.

3

4

```rust

5

use std::future::Future;

6

use std::ops::RangeBounds;

7

use std::pin::Pin;

8

use std::task::{Context, Poll};

9

use futures::Stream;

10

```

11

12

## Capabilities

13

14

### File Reading Operations

15

16

Read file content and metadata from storage backends.

17

18

```rust { .api }

19

impl Operator {

20

/// Read the entire content of a file

21

pub fn read(&self, path: &str) -> impl Future<Output = Result<Buffer>>;

22

23

/// Read file with advanced options (range, conditions)

24

pub fn read_with(&self, path: &str) -> FutureRead<impl Future<Output = Result<Buffer>>>;

25

26

/// Create a streaming reader for large files

27

pub fn reader(&self, path: &str) -> impl Future<Output = Result<Reader>>;

28

29

/// Create a streaming reader with options

30

pub fn reader_with(&self, path: &str) -> FutureReader<impl Future<Output = Result<Reader>>>;

31

32

/// Get file metadata without reading content

33

pub fn stat(&self, path: &str) -> impl Future<Output = Result<Metadata>>;

34

35

/// Get metadata with advanced options

36

pub fn stat_with(&self, path: &str) -> FutureStat<impl Future<Output = Result<Metadata>>>;

37

}

38

39

/// Future builder for read operations with options

40

pub struct FutureRead<F>;

41

impl<F> FutureRead<F> {

42

/// Set byte range to read (e.g., 0..1024)

43

pub fn range(self, range: impl RangeBounds<u64>) -> Self;

44

/// Set conditional read based on ETag match

45

pub fn if_match(self, etag: &str) -> Self;

46

/// Set conditional read based on ETag non-match

47

pub fn if_none_match(self, etag: &str) -> Self;

48

}

49

50

impl<F> Future for FutureRead<F>

51

where

52

F: Future<Output = Result<Buffer>>,

53

{

54

type Output = Result<Buffer>;

55

/// Execute the read operation

56

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;

57

}

58

59

/// Async streaming reader for large files

60

pub struct Reader;

61

impl Reader {

62

/// Read the next chunk of data

63

pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize>;

64

}

65

```

66

67

**Usage Examples:**

68

69

```rust

70

use opendal::{Operator, services};

71

72

// Read entire file

73

let content = op.read("data.txt").await?;

74

println!("Content: {}", String::from_utf8_lossy(&content));

75

76

// Read with byte range

77

let partial = op.read_with("large-file.dat")

78

.range(0..1024)

79

.await?;

80

81

// Streaming read for large files

82

let mut reader = op.reader("big-file.zip").await?;

83

let mut buffer = vec![0; 8192];

84

while let n = reader.read(&mut buffer).await? {

85

if n == 0 { break; }

86

// Process chunk

87

}

88

89

// Get file metadata

90

let meta = op.stat("document.pdf").await?;

91

println!("Size: {} bytes", meta.content_length());

92

println!("Modified: {:?}", meta.last_modified());

93

```

94

95

### File Writing Operations

96

97

Write data to storage backends with various options.

98

99

```rust { .api }

100

impl Operator {

101

/// Write data to a file, overwriting if exists

102

pub fn write(&self, path: &str, bs: impl Into<Buffer>) -> impl Future<Output = Result<()>>;

103

104

/// Write with advanced options (content type, cache control)

105

pub fn write_with(&self, path: &str, bs: impl Into<Buffer>) -> FutureWrite<impl Future<Output = Result<()>>>;

106

107

/// Create a streaming writer for large files

108

pub fn writer(&self, path: &str) -> impl Future<Output = Result<Writer>>;

109

110

/// Create streaming writer with options

111

pub fn writer_with(&self, path: &str) -> FutureWriter<impl Future<Output = Result<Writer>>>;

112

}

113

114

/// Future builder for write operations with options

115

pub struct FutureWrite;

116

impl FutureWrite {

117

/// Set content MIME type

118

pub fn content_type(mut self, content_type: &str) -> Self;

119

/// Set content disposition header

120

pub fn content_disposition(mut self, disposition: &str) -> Self;

121

/// Set cache control header

122

pub fn cache_control(mut self, cache_control: &str) -> Self;

123

/// Execute the write operation

124

pub async fn await(self) -> Result<()>;

125

}

126

127

/// Async streaming writer for large files

128

pub struct Writer;

129

impl Writer {

130

/// Write a chunk of data

131

pub async fn write(&mut self, bs: impl Into<Buffer>) -> Result<()>;

132

/// Finalize and close the writer

133

pub async fn close(self) -> Result<()>;

134

}

135

```

136

137

**Usage Examples:**

138

139

```rust

140

// Simple write

141

op.write("output.txt", "Hello, World!").await?;

142

143

// Write with content type

144

op.write_with("image.jpg", image_bytes)

145

.content_type("image/jpeg")

146

.cache_control("max-age=3600")

147

.await?;

148

149

// Streaming write for large files

150

let mut writer = op.writer("upload.bin").await?;

151

for chunk in large_data_chunks {

152

writer.write(chunk).await?;

153

}

154

writer.close().await?;

155

```

156

157

### Directory Operations

158

159

List and manage directory contents.

160

161

```rust { .api }

162

impl Operator {

163

/// List directory contents as a vector

164

pub fn list(&self, path: &str) -> impl Future<Output = Result<Vec<Entry>>>;

165

166

/// List directory with advanced options

167

pub fn list_with(&self, path: &str) -> FutureList;

168

169

/// Create streaming lister for large directories

170

pub fn lister(&self, path: &str) -> impl Future<Output = Result<Lister>>;

171

172

/// Create streaming lister with options

173

pub fn lister_with(&self, path: &str) -> FutureLister;

174

175

/// Create a directory

176

pub fn create_dir(&self, path: &str) -> impl Future<Output = Result<()>>;

177

}

178

179

/// Directory entry with metadata

180

pub struct Entry {

181

pub fn path(&self) -> &str;

182

pub fn metadata(&self) -> &Metadata;

183

pub fn mode(&self) -> EntryMode;

184

}

185

186

/// Entry type enumeration

187

pub enum EntryMode {

188

FILE,

189

DIR,

190

Unknown,

191

}

192

193

/// Future builder for list operations

194

pub struct FutureList;

195

impl FutureList {

196

/// List recursively through subdirectories

197

pub fn recursive(mut self, recursive: bool) -> Self;

198

/// Start listing after a specific path

199

pub fn start_after(mut self, path: &str) -> Self;

200

/// Specify which metadata to fetch

201

pub fn metakey(mut self, metakey: Metakey) -> Self;

202

}

203

204

/// Async streaming lister for large directories

205

pub struct Lister;

206

impl Lister {

207

/// Get the next entry

208

pub async fn next(&mut self) -> Result<Option<Entry>>;

209

}

210

```

211

212

**Usage Examples:**

213

214

```rust

215

// List directory contents

216

let entries = op.list("/photos/").await?;

217

for entry in entries {

218

println!("{}: {} bytes", entry.path(), entry.metadata().content_length());

219

}

220

221

// Recursive listing

222

let all_files = op.list_with("/documents/")

223

.recursive(true)

224

.await?;

225

226

// Streaming lister for large directories

227

let mut lister = op.lister("/logs/").await?;

228

while let Some(entry) = lister.next().await? {

229

if entry.mode() == EntryMode::FILE {

230

println!("File: {}", entry.path());

231

}

232

}

233

234

// Create directory

235

op.create_dir("/new-folder/").await?;

236

```

237

238

### File Management Operations

239

240

Copy, move, and delete files.

241

242

```rust { .api }

243

impl Operator {

244

/// Copy a file from source to destination

245

pub fn copy(&self, from: &str, to: &str) -> impl Future<Output = Result<()>>;

246

247

/// Rename/move a file from source to destination

248

pub fn rename(&self, from: &str, to: &str) -> impl Future<Output = Result<()>>;

249

250

/// Delete a single file

251

pub fn delete(&self, path: &str) -> impl Future<Output = Result<()>>;

252

}

253

```

254

255

**Usage Examples:**

256

257

```rust

258

// Copy file

259

op.copy("original.txt", "backup.txt").await?;

260

261

// Move/rename file

262

op.rename("old-name.doc", "new-name.doc").await?;

263

264

// Delete file

265

op.delete("temp-file.tmp").await?;

266

```

267

268

### Batch Operations

269

270

Efficient operations on multiple files.

271

272

```rust { .api }

273

impl Operator {

274

/// Delete multiple files in a single operation

275

pub fn remove(&self, paths: Vec<String>) -> impl Future<Output = Result<()>>;

276

277

/// Delete files from a stream (for very large lists)

278

pub fn remove_via(&self, input: impl Stream<Item = String> + Unpin) -> impl Future<Output = Result<()>>;

279

280

/// Recursively delete all files under a path

281

pub fn remove_all(&self, path: &str) -> impl Future<Output = Result<()>>;

282

}

283

```

284

285

**Usage Examples:**

286

287

```rust

288

use futures::stream;

289

290

// Batch delete specific files

291

let files_to_delete = vec![

292

"temp1.txt".to_string(),

293

"temp2.txt".to_string(),

294

"temp3.txt".to_string(),

295

];

296

op.remove(files_to_delete).await?;

297

298

// Stream-based delete for large lists

299

let file_stream = stream::iter(large_file_list);

300

op.remove_via(file_stream).await?;

301

302

// Recursively delete directory and contents

303

op.remove_all("/temp-data/").await?;

304

```

305

306

### Presigned URL Operations

307

308

Generate time-limited URLs for secure direct access.

309

310

```rust { .api }

311

impl Operator {

312

/// Generate presigned URL for reading

313

pub fn presign_read(&self, path: &str, expire: Duration) -> impl Future<Output = Result<PresignedRequest>>;

314

315

/// Generate presigned URL for writing

316

pub fn presign_write(&self, path: &str, expire: Duration) -> impl Future<Output = Result<PresignedRequest>>;

317

318

/// Generate presigned URL for metadata access

319

pub fn presign_stat(&self, path: &str, expire: Duration) -> impl Future<Output = Result<PresignedRequest>>;

320

321

/// Generate presigned URL with options

322

pub fn presign_read_with(&self, path: &str, expire: Duration) -> FuturePresignRead;

323

}

324

325

/// Presigned request details

326

pub struct PresignedRequest {

327

pub fn method(&self) -> &str;

328

pub fn uri(&self) -> &str;

329

pub fn headers(&self) -> &HeaderMap;

330

}

331

```

332

333

**Usage Examples:**

334

335

```rust

336

use std::time::Duration;

337

338

// Generate presigned download URL (valid for 1 hour)

339

let presigned = op.presign_read("private-file.pdf", Duration::from_secs(3600)).await?;

340

println!("Download URL: {}", presigned.uri());

341

342

// Generate presigned upload URL

343

let upload_req = op.presign_write("uploads/new-file.jpg", Duration::from_secs(1800)).await?;

344

// Client can now upload directly using the presigned URL

345

346

// Presigned URL with range

347

let partial_req = op.presign_read_with("large-file.bin", Duration::from_secs(300))

348

.range(0..1024)

349

.await?;

350

```

351

352

### Blocking Operations

353

354

Synchronous versions of all operations for non-async contexts.

355

356

```rust { .api }

357

impl BlockingOperator {

358

pub fn read(&self, path: &str) -> Result<Buffer>;

359

pub fn write(&self, path: &str, bs: impl Into<Buffer>) -> Result<()>;

360

pub fn stat(&self, path: &str) -> Result<Metadata>;

361

pub fn list(&self, path: &str) -> Result<Vec<Entry>>;

362

pub fn delete(&self, path: &str) -> Result<()>;

363

pub fn copy(&self, from: &str, to: &str) -> Result<()>;

364

pub fn rename(&self, from: &str, to: &str) -> Result<()>;

365

}

366

```

367

368

**Usage Examples:**

369

370

```rust

371

use opendal::BlockingOperator;

372

373

// Convert async operator to blocking

374

let blocking_op = op.blocking();

375

376

// Use synchronous operations

377

let content = blocking_op.read("data.txt")?;

378

blocking_op.write("output.txt", "Processed data")?;

379

let entries = blocking_op.list("/directory/")?;

380

```