or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

directory-operations.mdfile-descriptors.mdfile-operations.mdfile-watching.mdindex.mdstats-permissions.mdstreams.mdsymbolic-links.md

file-descriptors.mddocs/

0

# File Descriptors

1

2

Low-level file descriptor operations for fine-grained control over file access, positioning, and data manipulation. File descriptors provide precise control over file operations with manual buffer management.

3

4

## Capabilities

5

6

### File Opening

7

8

Open files and obtain file descriptors for low-level operations.

9

10

```javascript { .api }

11

/**

12

* Synchronously open a file and return a file descriptor

13

* @param path - File path to open

14

* @param flags - File open flags (string or number)

15

* @param mode - File mode for newly created files

16

* @returns File descriptor number

17

*/

18

openSync(path: string | Buffer, flags: string | number, mode?: number): number;

19

20

/**

21

* Asynchronously open a file and return a file descriptor

22

* @param path - File path to open

23

* @param flags - File open flags (string or number)

24

* @param mode - File mode for newly created files

25

* @param callback - Completion callback with file descriptor

26

*/

27

open(path: string | Buffer, flags: string | number, mode?: number, callback?: (err?: Error, fd?: number) => void): void;

28

open(path: string | Buffer, flags: string | number, callback: (err?: Error, fd?: number) => void): void;

29

```

30

31

**File Flags:**

32

- `'r'` - Open for reading (file must exist)

33

- `'r+'` - Open for reading and writing (file must exist)

34

- `'w'` - Open for writing (truncates file or creates new)

35

- `'wx'` - Open for writing exclusively (fails if file exists)

36

- `'w+'` - Open for reading and writing (truncates or creates)

37

- `'wx+'` - Open for reading and writing exclusively

38

39

**Usage Examples:**

40

41

```javascript

42

// Open file for reading

43

const fd = fs.openSync('/data.txt', 'r');

44

45

// Open for writing with specific mode

46

const writeFd = fs.openSync('/output.txt', 'w', 0o644);

47

48

// Open exclusively (fail if exists)

49

try {

50

const exclusiveFd = fs.openSync('/unique.txt', 'wx');

51

console.log('File opened exclusively');

52

} catch (err) {

53

console.log('File already exists');

54

}

55

56

// Async file opening

57

fs.open('/async.txt', 'r+', (err, fd) => {

58

if (!err) {

59

console.log('File opened with fd:', fd);

60

// Remember to close the file descriptor

61

fs.close(fd, () => {});

62

}

63

});

64

65

// Promise-based opening

66

const fd = await fs.promises.open('/promise.txt', 'w');

67

```

68

69

### File Closing

70

71

Close file descriptors to free system resources.

72

73

```javascript { .api }

74

/**

75

* Synchronously close a file descriptor

76

* @param fd - File descriptor to close

77

*/

78

closeSync(fd: number): void;

79

80

/**

81

* Asynchronously close a file descriptor

82

* @param fd - File descriptor to close

83

* @param callback - Completion callback

84

*/

85

close(fd: number, callback: (err?: Error) => void): void;

86

```

87

88

**Usage Examples:**

89

90

```javascript

91

// Open, use, and close file

92

const fd = fs.openSync('/temp.txt', 'w');

93

try {

94

// ... use file descriptor

95

fs.writeSync(fd, 'Hello World');

96

} finally {

97

fs.closeSync(fd); // Always close

98

}

99

100

// Async close

101

fs.open('/file.txt', 'r', (err, fd) => {

102

if (!err) {

103

// ... use fd

104

fs.close(fd, (closeErr) => {

105

if (!closeErr) {

106

console.log('File closed successfully');

107

}

108

});

109

}

110

});

111

```

112

113

### Reading with File Descriptors

114

115

Read data from files using file descriptors with precise buffer control.

116

117

```javascript { .api }

118

/**

119

* Synchronously read data from a file descriptor into a buffer

120

* @param fd - File descriptor to read from

121

* @param buffer - Buffer to write data into

122

* @param offset - Offset in buffer to start writing

123

* @param length - Number of bytes to read

124

* @param position - Position in file to read from (null for current position)

125

* @returns Number of bytes read

126

*/

127

readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null): number;

128

129

/**

130

* Asynchronously read data from a file descriptor into a buffer

131

* @param fd - File descriptor to read from

132

* @param buffer - Buffer to write data into

133

* @param offset - Offset in buffer to start writing

134

* @param length - Number of bytes to read

135

* @param position - Position in file to read from (null for current position)

136

* @param callback - Completion callback with bytes read

137

*/

138

read(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null, callback?: (err?: Error, bytesRead?: number) => void): void;

139

```

140

141

**Usage Examples:**

142

143

```javascript

144

// Read file content into buffer

145

const fd = fs.openSync('/data.txt', 'r');

146

const buffer = Buffer.alloc(1024);

147

148

try {

149

const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);

150

const content = buffer.subarray(0, bytesRead).toString('utf8');

151

console.log('Read content:', content);

152

} finally {

153

fs.closeSync(fd);

154

}

155

156

// Read from specific position

157

const fd2 = fs.openSync('/large-file.txt', 'r');

158

const chunk = Buffer.alloc(100);

159

const bytesRead = fs.readSync(fd2, chunk, 0, 100, 500); // Read 100 bytes from position 500

160

fs.closeSync(fd2);

161

162

// Async reading

163

fs.open('/async-read.txt', 'r', (err, fd) => {

164

if (err) return;

165

166

const buffer = Buffer.alloc(256);

167

fs.read(fd, buffer, 0, buffer.length, null, (readErr, bytesRead) => {

168

if (!readErr) {

169

const data = buffer.subarray(0, bytesRead);

170

console.log('Read data:', data.toString());

171

}

172

fs.close(fd, () => {});

173

});

174

});

175

```

176

177

### Writing with File Descriptors

178

179

Write data to files using file descriptors with precise positioning control.

180

181

```javascript { .api }

182

/**

183

* Synchronously write data from a buffer or string to a file descriptor

184

* @param fd - File descriptor to write to

185

* @param buffer - Buffer or string containing data to write

186

* @param offset - Offset in buffer to start reading from (for Buffer)

187

* @param length - Number of bytes to write (for Buffer)

188

* @param position - Position in file to write to (null for current position)

189

* @returns Number of bytes written

190

*/

191

writeSync(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number | null): number;

192

writeSync(fd: number, string: string, position?: number | null, encoding?: string): number;

193

194

/**

195

* Asynchronously write data from a buffer or string to a file descriptor

196

* @param fd - File descriptor to write to

197

* @param buffer - Buffer or string containing data to write

198

* @param offset - Offset in buffer to start reading from

199

* @param length - Number of bytes to write

200

* @param position - Position in file to write to (null for current position)

201

* @param callback - Completion callback with bytes written

202

*/

203

write(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number | null, callback?: (err?: Error, bytesWritten?: number) => void): void;

204

write(fd: number, string: string, position?: number | null, encoding?: string, callback?: (err?: Error, bytesWritten?: number) => void): void;

205

```

206

207

**Usage Examples:**

208

209

```javascript

210

// Write string to file

211

const fd = fs.openSync('/output.txt', 'w');

212

try {

213

const bytesWritten = fs.writeSync(fd, 'Hello, World!');

214

console.log(`Wrote ${bytesWritten} bytes`);

215

} finally {

216

fs.closeSync(fd);

217

}

218

219

// Write buffer to specific position

220

const fd2 = fs.openSync('/patchable.txt', 'r+');

221

const data = Buffer.from('patched');

222

fs.writeSync(fd2, data, 0, data.length, 10); // Write at position 10

223

fs.closeSync(fd2);

224

225

// Write with encoding

226

const fd3 = fs.openSync('/unicode.txt', 'w');

227

fs.writeSync(fd3, 'Hello 世界', 0, 'utf8');

228

fs.closeSync(fd3);

229

230

// Async writing

231

fs.open('/async-write.txt', 'w', (err, fd) => {

232

if (err) return;

233

234

const buffer = Buffer.from('Async data');

235

fs.write(fd, buffer, 0, buffer.length, null, (writeErr, bytesWritten) => {

236

if (!writeErr) {

237

console.log(`Wrote ${bytesWritten} bytes`);

238

}

239

fs.close(fd, () => {});

240

});

241

});

242

```

243

244

### File Descriptor Statistics

245

246

Get file information using file descriptors.

247

248

```javascript { .api }

249

/**

250

* Synchronously get file statistics using a file descriptor

251

* @param fd - File descriptor

252

* @returns Stats object with file information

253

*/

254

fstatSync(fd: number): Stats;

255

256

/**

257

* Asynchronously get file statistics using a file descriptor

258

* @param fd - File descriptor

259

* @param callback - Completion callback with stats

260

*/

261

fstat(fd: number, callback: (err?: Error, stats?: Stats) => void): void;

262

263

interface Stats {

264

isFile(): boolean;

265

isDirectory(): boolean;

266

isSymbolicLink(): boolean;

267

size: number;

268

mode: number;

269

uid: number;

270

gid: number;

271

atime: Date;

272

mtime: Date;

273

ctime: Date;

274

birthtime: Date;

275

// ... other properties

276

}

277

```

278

279

**Usage Examples:**

280

281

```javascript

282

// Get file stats using file descriptor

283

const fd = fs.openSync('/file.txt', 'r');

284

try {

285

const stats = fs.fstatSync(fd);

286

console.log(`File size: ${stats.size} bytes`);

287

console.log(`Is file: ${stats.isFile()}`);

288

console.log(`Modified: ${stats.mtime}`);

289

} finally {

290

fs.closeSync(fd);

291

}

292

293

// Async stats

294

fs.open('/data.txt', 'r', (err, fd) => {

295

if (err) return;

296

297

fs.fstat(fd, (statErr, stats) => {

298

if (!statErr) {

299

console.log('File info:', {

300

size: stats.size,

301

isFile: stats.isFile(),

302

modified: stats.mtime

303

});

304

}

305

fs.close(fd, () => {});

306

});

307

});

308

```

309

310

### File Descriptor Permissions

311

312

Change file permissions using file descriptors.

313

314

```javascript { .api }

315

/**

316

* Synchronously change file permissions using a file descriptor

317

* @param fd - File descriptor

318

* @param mode - New file mode (permissions)

319

*/

320

fchmodSync(fd: number, mode: number | string): void;

321

322

/**

323

* Asynchronously change file permissions using a file descriptor

324

* @param fd - File descriptor

325

* @param mode - New file mode (permissions)

326

* @param callback - Completion callback

327

*/

328

fchmod(fd: number, mode: number | string, callback?: (err?: Error) => void): void;

329

```

330

331

**Usage Examples:**

332

333

```javascript

334

// Change file permissions via file descriptor

335

const fd = fs.openSync('/secure.txt', 'r+');

336

try {

337

fs.fchmodSync(fd, 0o600); // Owner read/write only

338

console.log('Permissions changed');

339

} finally {

340

fs.closeSync(fd);

341

}

342

343

// Async permission change

344

fs.open('/data.txt', 'r+', (err, fd) => {

345

if (err) return;

346

347

fs.fchmod(fd, '644', (chmodErr) => {

348

if (!chmodErr) {

349

console.log('Permissions updated');

350

}

351

fs.close(fd, () => {});

352

});

353

});

354

```

355

356

### File Synchronization

357

358

Force file data to be written to storage.

359

360

```javascript { .api }

361

/**

362

* Synchronously force file data and metadata to be written to storage

363

* @param fd - File descriptor

364

*/

365

fsyncSync(fd: number): void;

366

367

/**

368

* Synchronously force file data (not metadata) to be written to storage

369

* @param fd - File descriptor

370

*/

371

fdatasyncSync(fd: number): void;

372

373

/**

374

* Asynchronously force file data and metadata to be written to storage

375

* @param fd - File descriptor

376

* @param callback - Completion callback

377

*/

378

fsync(fd: number, callback?: (err?: Error) => void): void;

379

380

/**

381

* Asynchronously force file data (not metadata) to be written to storage

382

* @param fd - File descriptor

383

* @param callback - Completion callback

384

*/

385

fdatasync(fd: number, callback?: (err?: Error) => void): void;

386

```

387

388

**Usage Examples:**

389

390

```javascript

391

// Ensure data is written to disk

392

const fd = fs.openSync('/critical.txt', 'w');

393

try {

394

fs.writeSync(fd, 'Important data');

395

fs.fsyncSync(fd); // Force write to disk

396

console.log('Data synchronized to storage');

397

} finally {

398

fs.closeSync(fd);

399

}

400

401

// Data-only sync (faster than fsync)

402

fs.fdatasyncSync(fd); // Sync data but not metadata

403

404

// Async sync

405

fs.open('/log.txt', 'w', (err, fd) => {

406

if (err) return;

407

408

fs.write(fd, 'Log entry', (writeErr) => {

409

if (writeErr) return;

410

411

fs.fsync(fd, (syncErr) => {

412

if (!syncErr) {

413

console.log('Log entry synchronized');

414

}

415

fs.close(fd, () => {});

416

});

417

});

418

});

419

```

420

421

## Best Practices

422

423

```javascript

424

// Always close file descriptors

425

function safeFileOperation(path) {

426

const fd = fs.openSync(path, 'r');

427

try {

428

// Perform operations

429

const buffer = Buffer.alloc(1024);

430

const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);

431

return buffer.subarray(0, bytesRead);

432

} finally {

433

fs.closeSync(fd); // Always close

434

}

435

}

436

437

// Use try-finally for exception safety

438

function writeToFile(path, data) {

439

const fd = fs.openSync(path, 'w');

440

try {

441

fs.writeSync(fd, data);

442

fs.fsyncSync(fd); // Ensure data is written

443

} finally {

444

fs.closeSync(fd);

445

}

446

}

447

448

// Handle async operations properly

449

function asyncFileRead(path, callback) {

450

fs.open(path, 'r', (err, fd) => {

451

if (err) return callback(err);

452

453

const buffer = Buffer.alloc(1024);

454

fs.read(fd, buffer, 0, buffer.length, 0, (readErr, bytesRead) => {

455

// Always close fd, even on error

456

fs.close(fd, (closeErr) => {

457

if (readErr) return callback(readErr);

458

if (closeErr) return callback(closeErr);

459

460

callback(null, buffer.subarray(0, bytesRead));

461

});

462

});

463

});

464

}

465

```

466

467

## Error Handling

468

469

Common file descriptor errors:

470

471

- `EBADF` - Bad file descriptor (already closed or invalid)

472

- `EMFILE` - Too many open files

473

- `ENOENT` - File doesn't exist (openSync with 'r' flag)

474

- `EEXIST` - File exists (openSync with 'wx' flag)

475

- `EISDIR` - Is a directory (cannot open directory as file)

476

- `EPERM` - Permission denied