585
586
private async doReadFileStream(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions & { preferUnbuffered?: boolean }, token?: CancellationToken): Promise<IFileStreamContent> {
588
>
// install a cancellation token that gets cancelled
589
>
// when any error occurs. this allows us to resolve
590
>
// the content of the file while resolving metadata
591
>
// but still cancel the operation in certain cases.
592
>
//
593
>
// in addition, we pass the optional token in that
594
>
// we got from the outside to even allow for external
595
>
// cancellation of the read operation.
596
>
const cancellableSource = new CancellationTokenSource(token);
597
>
598
>
let readFileOptions = options;
599
>
if (hasFileAtomicReadCapability(provider) && provider.enforceAtomicReadFile?.(resource)) {
600
readFileOptions = { ...options, atomic: true };
601
}
603
>
// validate read operation
604
>
const statPromise = this.validateReadFile(resource, readFileOptions).then(stat => stat, error => {
605
cancellableSource.dispose(true);
606
607
throw error;
609
>
610
>
let fileStream: VSBufferReadableStream | undefined = undefined;
611
>
try {
612
>
613
>
// if the etag is provided, we await the result of the validation
614
>
// due to the likelihood of hitting a NOT_MODIFIED_SINCE result.
615
>
// otherwise, we let it run in parallel to the file reading for
616
>
// optimal startup performance.
617
>
if (typeof readFileOptions?.etag === 'string' && readFileOptions.etag !== ETAG_DISABLED) {
618
await statPromise;
619
}
621
>
// read unbuffered
622
>
if (
623
>
(readFileOptions?.atomic && hasFileAtomicReadCapability(provider)) || // atomic reads are always unbuffered
624
>
!(hasOpenReadWriteCloseCapability(provider) || hasFileReadStreamCapability(provider)) || // provider has no buffered capability
625
>
(hasReadWriteCapability(provider) && readFileOptions?.preferUnbuffered) // unbuffered read is preferred
626
>
) {
627
fileStream = this.readFileUnbuffered(provider, resource, readFileOptions);
628
}