@@ -14,6 +14,7 @@ import { TernarySearchTree } from 'vs/base/common/map';
1414import { isNonEmptyArray , coalesce } from 'vs/base/common/arrays' ;
1515import { getBaseLabel } from 'vs/base/common/labels' ;
1616import { ILogService } from 'vs/platform/log/common/log' ;
17+ import { VSBuffer } from 'vs/base/common/buffer' ;
1718
1819export class FileService2 extends Disposable implements IFileService {
1920
@@ -39,6 +40,8 @@ export class FileService2 extends Disposable implements IFileService {
3940
4041 _serviceBrand : ServiceIdentifier < any > ;
4142
43+ private readonly BUFFER_SIZE = 16 * 1024 ;
44+
4245 constructor ( @ILogService private logService : ILogService ) {
4346 super ( ) ;
4447
@@ -316,12 +319,12 @@ export class FileService2 extends Disposable implements IFileService {
316319
317320 // create file: buffered
318321 if ( hasOpenReadWriteCloseCapability ( provider ) ) {
319- await this . doWriteBuffered ( provider , resource , new TextEncoder ( ) . encode ( content ) ) ;
322+ await this . doWriteBuffered ( provider , resource , VSBuffer . fromString ( content || '' ) ) ;
320323 }
321324
322325 // create file: unbuffered
323326 else if ( hasReadWriteCapability ( provider ) ) {
324- await this . doWriteUnbuffered ( provider , resource , new TextEncoder ( ) . encode ( content ) , overwrite ) ;
327+ await this . doWriteUnbuffered ( provider , resource , VSBuffer . fromString ( content || '' ) , overwrite ) ;
325328 }
326329
327330 // give up if provider has insufficient capabilities
@@ -657,7 +660,7 @@ export class FileService2 extends Disposable implements IFileService {
657660
658661 //#region Helpers
659662
660- private async doWriteBuffered ( provider : IFileSystemProviderWithOpenReadWriteCloseCapability , resource : URI , buffer : Uint8Array ) : Promise < void > {
663+ private async doWriteBuffered ( provider : IFileSystemProviderWithOpenReadWriteCloseCapability , resource : URI , buffer : VSBuffer ) : Promise < void > {
661664
662665 // open handle
663666 const handle = await provider . open ( resource , { create : true } ) ;
@@ -672,16 +675,16 @@ export class FileService2 extends Disposable implements IFileService {
672675 }
673676 }
674677
675- private async doWriteBuffer ( provider : IFileSystemProviderWithOpenReadWriteCloseCapability , handle : number , buffer : Uint8Array , length : number , posInFile : number , posInBuffer : number ) : Promise < void > {
678+ private async doWriteBuffer ( provider : IFileSystemProviderWithOpenReadWriteCloseCapability , handle : number , buffer : VSBuffer , length : number , posInFile : number , posInBuffer : number ) : Promise < void > {
676679 let totalBytesWritten = 0 ;
677680 while ( totalBytesWritten < length ) {
678- const bytesWritten = await provider . write ( handle , posInFile + totalBytesWritten , buffer , posInBuffer + totalBytesWritten , length - totalBytesWritten ) ;
681+ const bytesWritten = await provider . write ( handle , posInFile + totalBytesWritten , buffer . buffer , posInBuffer + totalBytesWritten , length - totalBytesWritten ) ;
679682 totalBytesWritten += bytesWritten ;
680683 }
681684 }
682685
683- private async doWriteUnbuffered ( provider : IFileSystemProviderWithFileReadWriteCapability , resource : URI , buffer : Uint8Array , overwrite : boolean ) : Promise < void > {
684- return provider . writeFile ( resource , buffer , { create : true , overwrite } ) ;
686+ private async doWriteUnbuffered ( provider : IFileSystemProviderWithFileReadWriteCapability , resource : URI , buffer : VSBuffer , overwrite : boolean ) : Promise < void > {
687+ return provider . writeFile ( resource , buffer . buffer , { create : true , overwrite } ) ;
685688 }
686689
687690 private async doPipeBuffered ( sourceProvider : IFileSystemProviderWithOpenReadWriteCloseCapability , source : URI , targetProvider : IFileSystemProviderWithOpenReadWriteCloseCapability , target : URI ) : Promise < void > {
@@ -694,15 +697,15 @@ export class FileService2 extends Disposable implements IFileService {
694697 sourceHandle = await sourceProvider . open ( source , { create : false } ) ;
695698 targetHandle = await targetProvider . open ( target , { create : true } ) ;
696699
697- const buffer = new Uint8Array ( 16 * 1024 ) ;
700+ const buffer = VSBuffer . alloc ( this . BUFFER_SIZE ) ;
698701
699702 let posInFile = 0 ;
700703 let posInBuffer = 0 ;
701704 let bytesRead = 0 ;
702705 do {
703706 // read from source (sourceHandle) at current position (posInFile) into buffer (buffer) at
704707 // buffer position (posInBuffer) up to the size of the buffer (buffer.byteLength).
705- bytesRead = await sourceProvider . read ( sourceHandle , posInFile , buffer , posInBuffer , buffer . byteLength - posInBuffer ) ;
708+ bytesRead = await sourceProvider . read ( sourceHandle , posInFile , buffer . buffer , posInBuffer , buffer . byteLength - posInBuffer ) ;
706709
707710 // write into target (targetHandle) at current position (posInFile) from buffer (buffer) at
708711 // buffer position (posInBuffer) all bytes we read (bytesRead).
@@ -712,7 +715,7 @@ export class FileService2 extends Disposable implements IFileService {
712715 posInBuffer += bytesRead ;
713716
714717 // when buffer full, fill it again from the beginning
715- if ( posInBuffer === buffer . length ) {
718+ if ( posInBuffer === buffer . byteLength ) {
716719 posInBuffer = 0 ;
717720 }
718721 } while ( bytesRead > 0 ) ;
@@ -738,7 +741,7 @@ export class FileService2 extends Disposable implements IFileService {
738741 // Read entire buffer from source and write buffered
739742 try {
740743 const buffer = await sourceProvider . readFile ( source ) ;
741- await this . doWriteBuffer ( targetProvider , targetHandle , buffer , buffer . byteLength , 0 , 0 ) ;
744+ await this . doWriteBuffer ( targetProvider , targetHandle , VSBuffer . wrap ( buffer ) , buffer . byteLength , 0 , 0 ) ;
742745 } catch ( error ) {
743746 throw error ;
744747 } finally {
@@ -748,27 +751,38 @@ export class FileService2 extends Disposable implements IFileService {
748751
749752 private async doPipeBufferedToUnbuffered ( sourceProvider : IFileSystemProviderWithOpenReadWriteCloseCapability , source : URI , targetProvider : IFileSystemProviderWithFileReadWriteCapability , target : URI , overwrite : boolean ) : Promise < void > {
750753
751- // Determine file size
752- const size = ( await this . resolve ( source , { resolveMetadata : true } ) ) . size ;
753-
754754 // Open handle
755755 const sourceHandle = await sourceProvider . open ( source , { create : false } ) ;
756756
757757 try {
758- const buffer = new Uint8Array ( size ) ;
758+ const buffers : VSBuffer [ ] = [ ] ;
759759
760- let pos = 0 ;
760+ let buffer = VSBuffer . alloc ( this . BUFFER_SIZE ) ;
761+
762+ let posInFile = 0 ;
763+ let totalBytesRead = 0 ;
761764 let bytesRead = 0 ;
765+ let posInBuffer = 0 ;
762766 do {
763- // read from source (sourceHandle) at current position (posInFile ) into buffer (buffer) at
767+ // read from source (sourceHandle) at current position (pos ) into buffer (buffer) at
764768 // buffer position (posInBuffer) up to the size of the buffer (buffer.byteLength).
765- bytesRead = await sourceProvider . read ( sourceHandle , pos , buffer , pos , buffer . byteLength - pos ) ;
769+ bytesRead = await sourceProvider . read ( sourceHandle , posInFile , buffer . buffer , posInBuffer , buffer . byteLength - posInBuffer ) ;
766770
767- pos += bytesRead ;
768- } while ( bytesRead > 0 && pos < size ) ;
771+ posInFile += bytesRead ;
772+ posInBuffer += bytesRead ;
773+ totalBytesRead += bytesRead ;
774+
775+ // when buffer full, create a new one
776+ if ( posInBuffer === buffer . byteLength ) {
777+ buffers . push ( buffer ) ;
778+ buffer = VSBuffer . alloc ( this . BUFFER_SIZE ) ;
779+
780+ posInBuffer = 0 ;
781+ }
782+ } while ( bytesRead > 0 ) ;
769783
770784 // Write buffer into target at once
771- await this . doWriteUnbuffered ( targetProvider , target , buffer , overwrite ) ;
785+ await this . doWriteUnbuffered ( targetProvider , target , VSBuffer . concat ( [ ... buffers , buffer . slice ( 0 , posInBuffer ) ] , totalBytesRead ) , overwrite ) ;
772786 } catch ( error ) {
773787 throw error ;
774788 } finally {
0 commit comments