or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

file-dialog.mdfile-resource.mdfile-service.mdfile-tree.mdfilesystem-core.mdfilesystem-preferences.mdindex.md

file-resource.mddocs/

0

# File Resource Management

1

2

Resource abstraction for files providing content management, encoding detection, version control, and seamless integration with Theia's resource framework. Enables treating files as managed resources with automatic encoding handling and change tracking.

3

4

## Capabilities

5

6

### FileResource Class

7

8

Core file resource implementation providing complete resource interface with file-specific functionality including encoding detection and conditional save operations.

9

10

```typescript { .api }

11

/**

12

* File resource implementation with encoding and version management

13

*/

14

class FileResource implements Resource {

15

/** File URI */

16

readonly uri: URI;

17

18

/** Resource version information with encoding and timestamps */

19

readonly version: FileResourceVersion | undefined;

20

21

/** Detected or specified file encoding */

22

readonly encoding: string | undefined;

23

24

/** Whether file is read-only (boolean or MarkdownString with reason) */

25

readonly readOnly: boolean | MarkdownString;

26

27

/** Read entire file contents as string with encoding handling */

28

readContents(options?: { encoding?: string }): Promise<string>;

29

30

/** Read file contents as stream with encoding handling */

31

readStream(options?: { encoding?: string }): Promise<ReadableStream<string>>;

32

33

/** Detect file encoding using heuristics and BOM detection */

34

guessEncoding(): Promise<string>;

35

36

/** Save string content to file (available when not read-only) */

37

saveContents?: (content: string, options?: SaveOptions) => Promise<void>;

38

39

/** Save content stream to file (available when not read-only) */

40

saveStream?: (content: ReadableStream<string>, options?: SaveOptions) => Promise<void>;

41

42

/** Apply content changes to file (available when not read-only) */

43

saveContentChanges?: (changes: TextDocumentContentChangeEvent[], options?: SaveOptions) => Promise<void>;

44

45

/** Resource disposal for cleanup */

46

dispose(): void;

47

}

48

```

49

50

### FileResourceVersion Interface

51

52

Version information for file resources including encoding, modification time, and entity tags for change detection.

53

54

```typescript { .api }

55

/**

56

* File resource version with encoding and timing information

57

*/

58

interface FileResourceVersion extends ResourceVersion {

59

/** Character encoding of the file */

60

readonly encoding: string;

61

62

/** Last modification time (Unix timestamp) */

63

readonly mtime: number;

64

65

/** Entity tag for change detection */

66

readonly etag: string;

67

}

68

69

interface ResourceVersion {

70

/** Unique version identifier */

71

readonly version: string;

72

}

73

```

74

75

### FileResourceResolver

76

77

Service for resolving URIs to FileResource instances with proper lifecycle management and caching.

78

79

```typescript { .api }

80

/**

81

* Resolver for creating FileResource instances from URIs

82

*/

83

@injectable()

84

class FileResourceResolver implements ResourceResolver {

85

/** Priority for this resolver (lower numbers = higher priority) */

86

readonly priority: number = -10;

87

88

/** Check if this resolver can handle the given URI */

89

canHandle(uri: URI): boolean;

90

91

/** Resolve URI to FileResource instance */

92

resolve(uri: URI): Promise<FileResource>;

93

94

/** Event fired when resources are created or disposed */

95

readonly onDidChangeContents: Event<URI>;

96

}

97

```

98

99

### Save Options

100

101

Configuration options for save operations including encoding, backup, and formatting preferences.

102

103

```typescript { .api }

104

/**

105

* Options for save operations

106

*/

107

interface SaveOptions {

108

/** Override encoding for this save operation */

109

encoding?: string;

110

111

/** Create backup before saving */

112

backup?: boolean;

113

114

/** Format document before saving */

115

format?: boolean;

116

117

/** Trim trailing whitespace */

118

trimTrailingWhitespace?: boolean;

119

120

/** Insert final newline if missing */

121

insertFinalNewline?: boolean;

122

123

/** Force save even if file hasn't changed */

124

force?: boolean;

125

}

126

```

127

128

### Text Document Content Changes

129

130

Change event types for incremental updates to file content.

131

132

```typescript { .api }

133

/**

134

* Incremental content change event

135

*/

136

interface TextDocumentContentChangeEvent {

137

/** Range being replaced (undefined for full document changes) */

138

range?: Range;

139

140

/** Length of replaced text */

141

rangeLength?: number;

142

143

/** New text content */

144

text: string;

145

}

146

147

interface Range {

148

/** Starting position */

149

start: Position;

150

151

/** Ending position */

152

end: Position;

153

}

154

155

interface Position {

156

/** Line number (zero-based) */

157

line: number;

158

159

/** Character offset (zero-based) */

160

character: number;

161

}

162

```

163

164

### Encoding Detection

165

166

Utility functions and constants for character encoding detection and handling.

167

168

```typescript { .api }

169

/**

170

* Common character encodings supported by FileResource

171

*/

172

enum Encoding {

173

UTF8 = 'utf8',

174

UTF16BE = 'utf16be',

175

UTF16LE = 'utf16le',

176

UTF32BE = 'utf32be',

177

UTF32LE = 'utf32le',

178

ASCII = 'ascii',

179

ISO88591 = 'iso88591',

180

WINDOWS1252 = 'windows1252'

181

}

182

183

/**

184

* Encoding detection result

185

*/

186

interface EncodingResult {

187

/** Detected encoding */

188

encoding: string;

189

190

/** Confidence level (0-1) */

191

confidence: number;

192

193

/** Whether BOM was detected */

194

hasBOM: boolean;

195

}

196

197

/**

198

* Detect encoding from binary data

199

*/

200

function detectEncoding(buffer: Uint8Array): EncodingResult;

201

202

/**

203

* Check if encoding is valid/supported

204

*/

205

function isValidEncoding(encoding: string): boolean;

206

```

207

208

**Usage Examples:**

209

210

```typescript

211

import { FileResource, FileResourceResolver } from "@theia/filesystem/lib/browser";

212

import { URI } from "@theia/core/lib/common/uri";

213

214

// Get resource resolver

215

const resolver = container.get(FileResourceResolver);

216

217

// Resolve file to resource

218

const fileUri = URI.parse('file:///workspace/src/main.ts');

219

const resource = await resolver.resolve(fileUri);

220

221

// Read file contents

222

const content = await resource.readContents();

223

console.log(`File content: ${content}`);

224

225

// Read with specific encoding

226

const contentUtf16 = await resource.readContents({ encoding: 'utf16le' });

227

228

// Check if file is read-only

229

if (typeof resource.readOnly === 'boolean' && !resource.readOnly) {

230

// File is writable

231

await resource.saveContents?.('console.log("Hello, World!");');

232

} else {

233

console.log('File is read-only');

234

if (typeof resource.readOnly !== 'boolean') {

235

console.log(`Reason: ${resource.readOnly.value}`);

236

}

237

}

238

239

// Stream reading for large files

240

const stream = await resource.readStream();

241

const reader = stream.getReader();

242

243

try {

244

while (true) {

245

const { done, value } = await reader.read();

246

if (done) break;

247

console.log('Chunk:', value);

248

}

249

} finally {

250

reader.releaseLock();

251

}

252

253

// Encoding detection

254

const encoding = await resource.guessEncoding();

255

console.log(`Detected encoding: ${encoding}`);

256

257

// Version information

258

if (resource.version) {

259

console.log(`Version: ${resource.version.version}`);

260

console.log(`Encoding: ${resource.version.encoding}`);

261

console.log(`Modified: ${new Date(resource.version.mtime)}`);

262

console.log(`ETag: ${resource.version.etag}`);

263

}

264

265

// Incremental updates

266

if (resource.saveContentChanges) {

267

await resource.saveContentChanges([{

268

range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },

269

text: '// Added comment\n'

270

}]);

271

}

272

273

// Save with options

274

await resource.saveContents?.('new content', {

275

encoding: 'utf8',

276

trimTrailingWhitespace: true,

277

insertFinalNewline: true,

278

format: true

279

});

280

281

// Resource cleanup

282

resource.dispose();

283

```

284

285

### Advanced Resource Operations

286

287

```typescript

288

import { ResourceProvider, Resource } from "@theia/core/lib/common/resource";

289

290

// Working with resource provider

291

const resourceProvider = container.get(ResourceProvider);

292

293

// Get or create resource

294

const resource = await resourceProvider.get(fileUri);

295

296

// Listen for content changes

297

resource.onDidChangeContents(uri => {

298

console.log(`Resource changed: ${uri.toString()}`);

299

});

300

301

// Batch operations with multiple resources

302

const resources = await Promise.all([

303

resourceProvider.get(URI.parse('file:///file1.txt')),

304

resourceProvider.get(URI.parse('file:///file2.txt')),

305

resourceProvider.get(URI.parse('file:///file3.txt'))

306

]);

307

308

// Read all contents in parallel

309

const contents = await Promise.all(

310

resources.map(resource => resource.readContents())

311

);

312

313

// Save all with same options

314

const saveOptions = { trimTrailingWhitespace: true, insertFinalNewline: true };

315

await Promise.all(

316

resources.map((resource, index) =>

317

resource.saveContents?.(contents[index].toUpperCase(), saveOptions)

318

)

319

);

320

321

// Binary file handling

322

const binaryResource = await resourceProvider.get(URI.parse('file:///image.png'));

323

const binaryContent = await binaryResource.readContents({ encoding: 'binary' });

324

```

325

326

### Custom Resource Implementations

327

328

```typescript

329

// Custom resource with additional functionality

330

class CustomFileResource extends FileResource {

331

332

// Add custom metadata

333

async getCustomMetadata(): Promise<any> {

334

// Custom implementation

335

return {};

336

}

337

338

// Override encoding detection with custom logic

339

async guessEncoding(): Promise<string> {

340

// Custom encoding detection logic

341

const detected = await super.guessEncoding();

342

343

// Apply custom rules

344

if (this.uri.path.endsWith('.log')) {

345

return 'ascii'; // Force ASCII for log files

346

}

347

348

return detected;

349

}

350

351

// Add validation before save

352

async saveContents(content: string, options?: SaveOptions): Promise<void> {

353

// Validate content before saving

354

if (!this.validateContent(content)) {

355

throw new Error('Invalid content format');

356

}

357

358

return super.saveContents!(content, options);

359

}

360

361

private validateContent(content: string): boolean {

362

// Custom validation logic

363

return content.length > 0;

364

}

365

}

366

```