0
# File Service Integration
1
2
Unified file service providing high-level file operations, encoding handling, streaming I/O, and event coordination across multiple file system providers. Acts as the central integration point for all file operations in Theia applications.
3
4
## Capabilities
5
6
### FileService Interface
7
8
Central service coordinating file operations across multiple providers with encoding handling, streaming, and event management.
9
10
```typescript { .api }
11
/**
12
* Unified API for all file system operations
13
*/
14
interface FileService {
15
/** Map of registered file system providers by scheme */
16
readonly providers: Map<string, FileSystemProvider>;
17
18
/** Register a file system provider for a URI scheme */
19
registerProvider(scheme: string, provider: FileSystemProvider): Disposable;
20
21
/** Get provider for a specific URI */
22
getProvider(resource: URI): FileSystemProvider | undefined;
23
24
/** Check if a provider exists for the URI scheme */
25
hasProvider(resource: URI): boolean;
26
27
/** Check provider capabilities for a resource */
28
hasCapability(resource: URI, capability: FileSystemProviderCapabilities): boolean;
29
30
/** Read file with automatic encoding detection and handling */
31
readFile(resource: URI, options?: ReadEncodingOptions): Promise<FileContent>;
32
33
/** Read file as stream with encoding handling */
34
readFileStream(resource: URI, options?: ReadEncodingOptions): Promise<FileStreamContent>;
35
36
/** Write file with encoding handling */
37
writeFile(resource: URI, content: string | Uint8Array, options?: WriteFileOptions): Promise<FileStat>;
38
39
/** Get file statistics */
40
stat(resource: URI): Promise<FileStat>;
41
42
/** List directory contents */
43
readdir(resource: URI): Promise<FileStat[]>;
44
45
/** Create directory */
46
createFolder(resource: URI): Promise<FileStat>;
47
48
/** Delete file or directory */
49
delete(resource: URI, options?: DeleteFileOptions): Promise<void>;
50
51
/** Move/rename file or directory */
52
move(source: URI, target: URI, options?: MoveFileOptions): Promise<FileStat>;
53
54
/** Copy file or directory */
55
copy(source: URI, target: URI, options?: CopyFileOptions): Promise<FileStat>;
56
57
/** File system change events */
58
readonly onDidFilesChange: Event<FileChangesEvent>;
59
60
/** File operation events */
61
readonly onDidRunFileOperation: Event<FileOperationEvent>;
62
63
/** Provider registration events */
64
readonly onDidChangeFileSystemProviderRegistrations: Event<FileSystemProviderRegistrationEvent>;
65
}
66
```
67
68
### Text File Operations
69
70
Specialized operations for text files with encoding detection and handling.
71
72
```typescript { .api }
73
/**
74
* Text file content with encoding information
75
*/
76
interface TextFileContent {
77
/** File resource URI */
78
readonly resource: URI;
79
80
/** Text content as string */
81
readonly value: string;
82
83
/** Character encoding used */
84
readonly encoding: string;
85
86
/** File statistics */
87
readonly stat: FileStat;
88
89
/** Version information */
90
readonly version: FileResourceVersion;
91
}
92
93
/**
94
* Streaming text file content
95
*/
96
interface TextFileStreamContent {
97
/** File resource URI */
98
readonly resource: URI;
99
100
/** Text content as readable stream */
101
readonly value: ReadableStream<string>;
102
103
/** Character encoding used */
104
readonly encoding: string;
105
106
/** File statistics */
107
readonly stat: FileStat;
108
109
/** Version information */
110
readonly version: FileResourceVersion;
111
}
112
113
/**
114
* Read text file with encoding options
115
*/
116
interface ReadTextFileOptions extends ReadEncodingOptions {
117
/** Accept text files over this size with confirmation */
118
acceptTextOnly?: boolean;
119
120
/** Maximum file size to read */
121
limits?: {
122
/** Maximum file size in bytes */
123
size?: number;
124
};
125
}
126
```
127
128
### File Operation Options
129
130
Comprehensive options for various file operations including overwrite behavior, encoding, and formatting.
131
132
```typescript { .api }
133
/**
134
* Options for reading files with encoding
135
*/
136
interface ReadEncodingOptions {
137
/** Override encoding detection */
138
encoding?: string;
139
140
/** Whether to auto-detect encoding */
141
autoGuessEncoding?: boolean;
142
}
143
144
/**
145
* Options for writing files
146
*/
147
interface WriteFileOptions extends WriteEncodingOptions {
148
/** Create file if it doesn't exist */
149
create?: boolean;
150
151
/** Overwrite existing file */
152
overwrite?: boolean;
153
154
/** Unlock readonly files */
155
unlock?: boolean;
156
157
/** Atomic write operation */
158
atomic?: boolean;
159
}
160
161
/**
162
* Encoding options for writing
163
*/
164
interface WriteEncodingOptions {
165
/** Character encoding to use */
166
encoding?: string;
167
168
/** Write BOM for UTF encodings */
169
writeBOM?: boolean;
170
}
171
172
/**
173
* Options for deleting files/directories
174
*/
175
interface DeleteFileOptions {
176
/** Delete recursively for directories */
177
recursive?: boolean;
178
179
/** Move to trash instead of permanent deletion */
180
useTrash?: boolean;
181
182
/** Skip confirmation dialogs */
183
skipConfirm?: boolean;
184
}
185
186
/**
187
* Options for moving/renaming files
188
*/
189
interface MoveFileOptions {
190
/** Overwrite existing target */
191
overwrite?: boolean;
192
193
/** Skip confirmation dialogs */
194
skipConfirm?: boolean;
195
}
196
197
/**
198
* Options for copying files
199
*/
200
interface CopyFileOptions {
201
/** Overwrite existing target */
202
overwrite?: boolean;
203
204
/** Skip confirmation dialogs */
205
skipConfirm?: boolean;
206
207
/** Preserve original timestamps */
208
preserveTimestamps?: boolean;
209
}
210
```
211
212
### File Operation Participants
213
214
Extension mechanism allowing other services to participate in file operations for validation, transformation, or logging.
215
216
```typescript { .api }
217
/**
218
* Participant in file operations for validation or transformation
219
*/
220
interface FileOperationParticipant {
221
/** Participate in file operation before execution */
222
participate(
223
files: SourceTargetPair[],
224
operation: FileOperation,
225
timeout: number,
226
token: CancellationToken
227
): Promise<void>;
228
}
229
230
/**
231
* Source and target pair for file operations
232
*/
233
interface SourceTargetPair {
234
/** Source file URI */
235
source?: URI;
236
237
/** Target file URI */
238
target: URI;
239
}
240
241
/**
242
* Register file operation participant
243
*/
244
function registerFileOperationParticipant(participant: FileOperationParticipant): Disposable;
245
```
246
247
### Provider Registration Events
248
249
Events for tracking file system provider registration and changes.
250
251
```typescript { .api }
252
/**
253
* File system provider registration event
254
*/
255
interface FileSystemProviderRegistrationEvent {
256
/** URI scheme being registered/unregistered */
257
readonly scheme: string;
258
259
/** Provider instance (undefined for unregistration) */
260
readonly provider?: FileSystemProvider;
261
262
/** Whether this is a registration or unregistration */
263
readonly added: boolean;
264
}
265
```
266
267
### Text File Operations
268
269
Specialized high-level operations for text files with encoding detection, content updates, and streaming support.
270
271
```typescript { .api }
272
/**
273
* Extended file service interface with text file operations
274
*/
275
interface FileService {
276
/** Read text file with encoding detection and handling */
277
readTextContent(resource: URI, options?: ReadTextFileOptions): Promise<TextFileContent>;
278
279
/** Read text file as stream with encoding handling */
280
readTextContentStream(resource: URI, options?: ReadTextFileOptions): Promise<TextFileStreamContent>;
281
282
/** Write text content to file with encoding */
283
writeTextContent(resource: URI, content: string, options?: WriteTextFileOptions): Promise<FileStatWithMetadata & { encoding: string }>;
284
285
/** Create new text file with content */
286
createTextFile(resource: URI, content?: string, options?: CreateTextFileOptions): Promise<FileStatWithMetadata>;
287
288
/** Update text file with incremental changes */
289
updateTextFile(resource: URI, changes: TextDocumentContentChangeEvent[], options: UpdateTextFileOptions): Promise<FileStatWithMetadata & { encoding: string }>;
290
}
291
292
/**
293
* Text file content with encoding information
294
*/
295
interface TextFileContent extends BaseStatWithMetadata {
296
/** Text content of the file */
297
readonly value: string;
298
299
/** Character encoding used */
300
readonly encoding: string;
301
}
302
303
/**
304
* Streaming text file content
305
*/
306
interface TextFileStreamContent extends BaseStatWithMetadata {
307
/** Text content as readable stream */
308
readonly value: ReadableStream<string>;
309
310
/** Character encoding used */
311
readonly encoding: string;
312
}
313
314
/**
315
* Text file operation specific error
316
*/
317
class TextFileOperationError extends FileOperationError {
318
constructor(
319
message: string,
320
public textFileOperationResult: TextFileOperationResult,
321
options?: ReadTextFileOptions & WriteTextFileOptions
322
);
323
}
324
325
enum TextFileOperationResult {
326
FILE_IS_BINARY
327
}
328
329
/**
330
* Options for text file operations
331
*/
332
interface ReadTextFileOptions extends ReadEncodingOptions, ReadFileOptions {
333
/** Accept text files only, fail if binary */
334
acceptTextOnly?: boolean;
335
}
336
337
interface CreateTextFileOptions extends WriteEncodingOptions, CreateFileOptions {}
338
339
interface WriteTextFileOptions extends WriteEncodingOptions, WriteFileOptions {}
340
341
interface UpdateTextFileOptions extends WriteEncodingOptions, WriteFileOptions {
342
/** Encoding used when reading the file */
343
readEncoding: string;
344
}
345
346
interface WriteEncodingOptions {
347
/** Encoding to use when writing */
348
encoding?: string;
349
350
/** Enforce encoding without BOM detection */
351
overwriteEncoding?: boolean;
352
}
353
```
354
355
### File Upload Service
356
357
Service for uploading files from client to server with progress tracking and drag-and-drop support.
358
359
```typescript { .api }
360
/**
361
* File upload service with progress tracking
362
*/
363
interface FileUploadService {
364
/** Event fired when files are uploaded */
365
readonly onDidUpload: Event<string[]>;
366
367
/** Maximum concurrent uploads allowed */
368
readonly maxConcurrentUploads: number;
369
370
/** Upload files to target location */
371
upload(targetUri: string | URI, params?: FileUploadParams): Promise<FileUploadResult>;
372
}
373
374
/**
375
* File upload parameters and options
376
*/
377
interface FileUploadParams {
378
/** Source data (drag-and-drop or file input) */
379
source?: DataTransfer | CustomDataTransfer;
380
381
/** Progress tracking options */
382
progress?: FileUploadProgressParams;
383
384
/** Callback when upload completes */
385
onDidUpload?: (uri: string) => void;
386
387
/** Keep files in temporary directory */
388
leaveInTemp?: boolean;
389
}
390
391
interface FileUploadProgressParams {
392
/** Progress display text */
393
text: string;
394
}
395
396
interface FileUploadResult {
397
/** Array of uploaded file URIs */
398
uploaded: string[];
399
}
400
401
/**
402
* Upload endpoint and URL constants
403
*/
404
const HTTP_FILE_UPLOAD_PATH = '/file-upload';
405
const HTTP_UPLOAD_URL: string;
406
```
407
408
### File Download Service
409
410
Service for downloading files and directories with compression and link copying support.
411
412
```typescript { .api }
413
/**
414
* File download service
415
*/
416
interface FileDownloadService {
417
/** Download files or directories */
418
download(uris: URI[], options?: DownloadOptions): Promise<void>;
419
420
/** Cancel ongoing download */
421
cancelDownload(id: string): Promise<void>;
422
}
423
424
/**
425
* Download operation options
426
*/
427
interface DownloadOptions {
428
/** Copy download link to clipboard instead of downloading */
429
readonly copyLink?: boolean;
430
}
431
432
/**
433
* Download data structure
434
*/
435
interface FileDownloadData {
436
/** Array of file URIs to download */
437
readonly uris: string[];
438
}
439
```
440
441
**Usage Examples:**
442
443
```typescript
444
import {
445
FileService, TextFileContent, FileUploadService,
446
FileDownloadService
447
} from "@theia/filesystem/lib/browser";
448
import { URI } from "@theia/core/lib/common/uri";
449
450
// Get file service instance
451
const fileService = container.get(FileService);
452
453
// Basic file operations
454
const fileUri = URI.parse('file:///workspace/readme.txt');
455
456
// Read file with encoding detection
457
const content = await fileService.readFile(fileUri);
458
console.log(`Content: ${content.value.toString()}`);
459
console.log(`Encoding: ${content.encoding}`);
460
console.log(`Size: ${content.stat.size} bytes`);
461
462
// Read file with specific encoding
463
const contentUtf16 = await fileService.readFile(fileUri, {
464
encoding: 'utf16le'
465
});
466
467
// Write file with encoding
468
await fileService.writeFile(
469
URI.parse('file:///workspace/output.txt'),
470
'Hello, World!',
471
{
472
encoding: 'utf8',
473
create: true,
474
overwrite: true
475
}
476
);
477
478
// Stream reading for large files
479
const streamContent = await fileService.readFileStream(fileUri);
480
const reader = streamContent.value.getReader();
481
482
try {
483
while (true) {
484
const { done, value } = await reader.read();
485
if (done) break;
486
console.log('Chunk:', value);
487
}
488
} finally {
489
reader.releaseLock();
490
}
491
492
// Directory operations
493
const dirUri = URI.parse('file:///workspace/src');
494
495
// List directory contents
496
const entries = await fileService.readdir(dirUri);
497
for (const entry of entries) {
498
console.log(`${entry.name}: ${entry.isFile ? 'file' : 'directory'}`);
499
}
500
501
// Create directory
502
const newDirUri = URI.parse('file:///workspace/new-folder');
503
await fileService.createFolder(newDirUri);
504
505
// File operations
506
const sourceUri = URI.parse('file:///workspace/source.txt');
507
const targetUri = URI.parse('file:///workspace/target.txt');
508
509
// Copy file
510
await fileService.copy(sourceUri, targetUri, {
511
overwrite: true,
512
preserveTimestamps: true
513
});
514
515
// Move/rename file
516
await fileService.move(sourceUri, URI.parse('file:///workspace/renamed.txt'), {
517
overwrite: false
518
});
519
520
// Delete file
521
await fileService.delete(targetUri, {
522
useTrash: true
523
});
524
525
// Event handling
526
fileService.onDidFilesChange(event => {
527
console.log(`${event.changes.length} files changed`);
528
529
for (const change of event.changes) {
530
console.log(`${FileChangeType[change.type]}: ${change.resource.toString()}`);
531
}
532
});
533
534
fileService.onDidRunFileOperation(event => {
535
console.log(`Operation: ${FileOperation[event.operation]}`);
536
console.log(`Target: ${event.target.toString()}`);
537
if (event.source) {
538
console.log(`Source: ${event.source.toString()}`);
539
}
540
});
541
542
// Provider management
543
const customProvider = new CustomFileSystemProvider();
544
const disposable = fileService.registerProvider('custom', customProvider);
545
546
// Check provider capabilities
547
const hasWriteCapability = fileService.hasCapability(
548
URI.parse('custom://example'),
549
FileSystemProviderCapabilities.FileReadWrite
550
);
551
552
// Get specific provider
553
const provider = fileService.getProvider(URI.parse('file:///example'));
554
if (provider) {
555
// Direct provider operations
556
const stat = await provider.stat(URI.parse('file:///example'));
557
}
558
559
// Cleanup
560
disposable.dispose();
561
```
562
563
### Advanced Service Usage
564
565
```typescript
566
// Custom file operation participant
567
class ValidationParticipant implements FileOperationParticipant {
568
569
async participate(
570
files: SourceTargetPair[],
571
operation: FileOperation,
572
timeout: number,
573
token: CancellationToken
574
): Promise<void> {
575
576
for (const { source, target } of files) {
577
// Validate operation
578
if (operation === FileOperation.DELETE && target.path.includes('important')) {
579
throw new Error('Cannot delete important files');
580
}
581
582
// Transform paths
583
if (operation === FileOperation.CREATE && source) {
584
// Custom logic for file creation
585
}
586
}
587
}
588
}
589
590
// Register participant
591
const participant = new ValidationParticipant();
592
const disposable = registerFileOperationParticipant(participant);
593
594
// Batch operations
595
const files = [
596
URI.parse('file:///file1.txt'),
597
URI.parse('file:///file2.txt'),
598
URI.parse('file:///file3.txt')
599
];
600
601
// Read multiple files in parallel
602
const contents = await Promise.all(
603
files.map(uri => fileService.readFile(uri))
604
);
605
606
// Write multiple files with same options
607
const writeOptions = { encoding: 'utf8', create: true };
608
await Promise.all(
609
contents.map((content, index) =>
610
fileService.writeFile(
611
URI.parse(`file:///output${index}.txt`),
612
content.value.toString().toUpperCase(),
613
writeOptions
614
)
615
)
616
);
617
618
// Complex file operations with error handling
619
async function safeFileOperation(uri: URI) {
620
try {
621
// Check if provider exists
622
if (!fileService.hasProvider(uri)) {
623
throw new Error(`No provider for scheme: ${uri.scheme}`);
624
}
625
626
// Check capabilities
627
if (!fileService.hasCapability(uri, FileSystemProviderCapabilities.FileReadWrite)) {
628
throw new Error('Provider does not support read/write operations');
629
}
630
631
// Perform operation
632
const content = await fileService.readFile(uri);
633
return content;
634
635
} catch (error) {
636
console.error(`File operation failed for ${uri.toString()}:`, error);
637
throw error;
638
}
639
}
640
```