Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
徽霖
Vscode
提交
0dcdc6a3
V
Vscode
项目概览
徽霖
/
Vscode
通知
9
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
Vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
0dcdc6a3
编写于
7月 11, 2019
作者:
B
Benjamin Pasero
提交者:
GitHub
7月 11, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
files - first cut allow stream for writeFile (#77172)
上级
46cc0a16
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
108 addition
and
27 deletion
+108
-27
src/vs/base/common/buffer.ts
src/vs/base/common/buffer.ts
+6
-0
src/vs/workbench/services/files/common/fileService.ts
src/vs/workbench/services/files/common/fileService.ts
+59
-26
src/vs/workbench/services/files/test/node/diskFileService.test.ts
...orkbench/services/files/test/node/diskFileService.test.ts
+43
-1
未找到文件。
src/vs/base/common/buffer.ts
浏览文件 @
0dcdc6a3
...
...
@@ -182,6 +182,12 @@ export interface VSBufferReadableStream {
destroy
():
void
;
}
export
function
isVSBufferReadableStream
(
obj
:
any
):
obj
is
VSBufferReadableStream
{
const
candidate
:
VSBufferReadableStream
=
obj
;
return
candidate
&&
[
candidate
.
on
,
candidate
.
pause
,
candidate
.
resume
,
candidate
.
destroy
].
every
(
fn
=>
typeof
fn
===
'
function
'
);
}
/**
* Helper to fully read a VSBuffer readable into a single buffer.
*/
...
...
src/vs/workbench/services/files/common/fileService.ts
浏览文件 @
0dcdc6a3
...
...
@@ -14,7 +14,7 @@ import { TernarySearchTree } from 'vs/base/common/map';
import
{
isNonEmptyArray
,
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
getBaseLabel
}
from
'
vs/base/common/labels
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
VSBuffer
,
VSBufferReadable
,
readableToBuffer
,
bufferToReadable
,
streamToBuffer
,
bufferToStream
,
VSBufferReadableStream
,
writeableBufferStream
,
VSBufferWriteableStream
}
from
'
vs/base/common/buffer
'
;
import
{
VSBuffer
,
VSBufferReadable
,
readableToBuffer
,
bufferToReadable
,
streamToBuffer
,
bufferToStream
,
VSBufferReadableStream
,
writeableBufferStream
,
VSBufferWriteableStream
,
isVSBufferReadableStream
}
from
'
vs/base/common/buffer
'
;
import
{
Queue
}
from
'
vs/base/common/async
'
;
import
{
CancellationTokenSource
,
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
...
...
@@ -281,7 +281,7 @@ export class FileService extends Disposable implements IFileService {
return
fileStat
;
}
async
writeFile
(
resource
:
URI
,
bufferOrReadable
:
VSBuffer
|
VSBufferReadable
,
options
?:
IWriteFileOptions
):
Promise
<
IFileStatWithMetadata
>
{
async
writeFile
(
resource
:
URI
,
bufferOrReadable
OrStream
:
VSBuffer
|
VSBufferReadable
|
VSBufferReadableStream
,
options
?:
IWriteFileOptions
):
Promise
<
IFileStatWithMetadata
>
{
const
provider
=
this
.
throwIfFileSystemIsReadonly
(
await
this
.
withReadWriteProvider
(
resource
));
try
{
...
...
@@ -296,12 +296,12 @@ export class FileService extends Disposable implements IFileService {
// write file: buffered
if
(
hasOpenReadWriteCloseCapability
(
provider
))
{
await
this
.
doWriteBuffered
(
provider
,
resource
,
bufferOrReadable
instanceof
VSBuffer
?
bufferToReadable
(
bufferOrReadable
)
:
bufferOrReadable
);
await
this
.
doWriteBuffered
(
provider
,
resource
,
bufferOrReadable
OrStream
instanceof
VSBuffer
?
bufferToReadable
(
bufferOrReadableOrStream
)
:
bufferOrReadableOrStream
);
}
// write file: unbuffered
else
{
await
this
.
doWriteUnbuffered
(
provider
,
resource
,
bufferOrReadable
);
await
this
.
doWriteUnbuffered
(
provider
,
resource
,
bufferOrReadable
OrStream
);
}
}
catch
(
error
)
{
throw
new
FileOperationError
(
localize
(
'
err.write
'
,
"
Unable to write file ({0})
"
,
this
.
ensureError
(
error
).
toString
()),
toFileOperationResult
(
error
),
options
);
...
...
@@ -857,29 +857,60 @@ export class FileService extends Disposable implements IFileService {
return
isPathCaseSensitive
?
resource
.
toString
()
:
resource
.
toString
().
toLowerCase
();
}
private
async
doWriteBuffered
(
provider
:
IFileSystemProviderWithOpenReadWriteCloseCapability
,
resource
:
URI
,
readable
:
VSBufferReadable
):
Promise
<
void
>
{
return
this
.
ensureWriteQueue
(
provider
,
resource
).
queue
(()
=>
this
.
doWriteBufferedQueued
(
provider
,
resource
,
readable
));
}
private
async
doWriteBuffered
(
provider
:
IFileSystemProviderWithOpenReadWriteCloseCapability
,
resource
:
URI
,
readableOrStream
:
VSBufferReadable
|
VSBufferReadableStream
):
Promise
<
void
>
{
return
this
.
ensureWriteQueue
(
provider
,
resource
).
queue
(
async
()
=>
{
private
async
doWriteBufferedQueued
(
provider
:
IFileSystemProviderWithOpenReadWriteCloseCapability
,
resource
:
URI
,
readable
:
VSBufferReadable
):
Promise
<
void
>
{
// open handle
const
handle
=
await
provider
.
open
(
resource
,
{
create
:
true
});
// open handle
const
handle
=
await
provider
.
open
(
resource
,
{
create
:
true
});
// write into handle until all bytes from buffer have been written
try
{
if
(
isVSBufferReadableStream
(
readableOrStream
))
{
await
this
.
doWriteStreamBufferedQueued
(
provider
,
handle
,
readableOrStream
);
}
else
{
await
this
.
doWriteReadableBufferedQueued
(
provider
,
handle
,
readableOrStream
);
}
}
catch
(
error
)
{
throw
this
.
ensureError
(
error
);
}
finally
{
// write into handle until all bytes from buffer have been written
try
{
// close handle always
await
provider
.
close
(
handle
);
}
});
}
private
doWriteStreamBufferedQueued
(
provider
:
IFileSystemProviderWithOpenReadWriteCloseCapability
,
handle
:
number
,
stream
:
VSBufferReadableStream
):
Promise
<
void
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
let
posInFile
=
0
;
let
chunk
:
VSBuffer
|
null
;
while
(
chunk
=
readable
.
read
())
{
await
this
.
doWriteBuffer
(
provider
,
handle
,
chunk
,
chunk
.
byteLength
,
posInFile
,
0
);
stream
.
on
(
'
data
'
,
async
chunk
=>
{
stream
.
pause
();
try
{
await
this
.
doWriteBuffer
(
provider
,
handle
,
chunk
,
chunk
.
byteLength
,
posInFile
,
0
);
}
catch
(
error
)
{
reject
(
error
);
}
posInFile
+=
chunk
.
byteLength
;
}
}
catch
(
error
)
{
throw
this
.
ensureError
(
error
);
}
finally
{
await
provider
.
close
(
handle
);
stream
.
resume
();
});
stream
.
on
(
'
error
'
,
error
=>
reject
(
error
));
stream
.
on
(
'
end
'
,
()
=>
resolve
());
});
}
private
async
doWriteReadableBufferedQueued
(
provider
:
IFileSystemProviderWithOpenReadWriteCloseCapability
,
handle
:
number
,
readable
:
VSBufferReadable
):
Promise
<
void
>
{
let
posInFile
=
0
;
let
chunk
:
VSBuffer
|
null
;
while
(
chunk
=
readable
.
read
())
{
await
this
.
doWriteBuffer
(
provider
,
handle
,
chunk
,
chunk
.
byteLength
,
posInFile
,
0
);
posInFile
+=
chunk
.
byteLength
;
}
}
...
...
@@ -891,16 +922,18 @@ export class FileService extends Disposable implements IFileService {
}
}
private
async
doWriteUnbuffered
(
provider
:
IFileSystemProviderWithFileReadWriteCapability
,
resource
:
URI
,
bufferOrReadable
:
VSBuffer
|
VSBufferReadable
):
Promise
<
void
>
{
return
this
.
ensureWriteQueue
(
provider
,
resource
).
queue
(()
=>
this
.
doWriteUnbufferedQueued
(
provider
,
resource
,
bufferOrReadable
));
private
async
doWriteUnbuffered
(
provider
:
IFileSystemProviderWithFileReadWriteCapability
,
resource
:
URI
,
bufferOrReadable
OrStream
:
VSBuffer
|
VSBufferReadable
|
VSBufferReadableStream
):
Promise
<
void
>
{
return
this
.
ensureWriteQueue
(
provider
,
resource
).
queue
(()
=>
this
.
doWriteUnbufferedQueued
(
provider
,
resource
,
bufferOrReadable
OrStream
));
}
private
async
doWriteUnbufferedQueued
(
provider
:
IFileSystemProviderWithFileReadWriteCapability
,
resource
:
URI
,
bufferOrReadable
:
VSBuffer
|
VSBufferReadable
):
Promise
<
void
>
{
private
async
doWriteUnbufferedQueued
(
provider
:
IFileSystemProviderWithFileReadWriteCapability
,
resource
:
URI
,
bufferOrReadable
OrStream
:
VSBuffer
|
VSBufferReadable
|
VSBufferReadableStream
):
Promise
<
void
>
{
let
buffer
:
VSBuffer
;
if
(
bufferOrReadable
instanceof
VSBuffer
)
{
buffer
=
bufferOrReadable
;
if
(
bufferOrReadableOrStream
instanceof
VSBuffer
)
{
buffer
=
bufferOrReadableOrStream
;
}
else
if
(
isVSBufferReadableStream
(
bufferOrReadableOrStream
))
{
buffer
=
await
streamToBuffer
(
bufferOrReadableOrStream
);
}
else
{
buffer
=
readableToBuffer
(
bufferOrReadable
);
buffer
=
readableToBuffer
(
bufferOrReadable
OrStream
);
}
return
provider
.
writeFile
(
resource
,
buffer
.
buffer
,
{
create
:
true
,
overwrite
:
true
});
...
...
src/vs/workbench/services/files/test/node/diskFileService.test.ts
浏览文件 @
0dcdc6a3
...
...
@@ -20,7 +20,7 @@ import { NullLogService } from 'vs/platform/log/common/log';
import
{
isLinux
,
isWindows
}
from
'
vs/base/common/platform
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
isEqual
}
from
'
vs/base/common/resources
'
;
import
{
VSBuffer
,
VSBufferReadable
}
from
'
vs/base/common/buffer
'
;
import
{
VSBuffer
,
VSBufferReadable
,
bufferToStream
}
from
'
vs/base/common/buffer
'
;
function
getByName
(
root
:
IFileStat
,
name
:
string
):
IFileStat
|
null
{
if
(
root
.
children
===
undefined
)
{
...
...
@@ -1545,6 +1545,48 @@ suite('Disk File Service', () => {
assert
.
equal
(
readFileSync
(
resource
.
fsPath
),
newContent
);
});
test
(
'
writeFile (large file - stream) - buffered
'
,
async
()
=>
{
setCapabilities
(
fileProvider
,
FileSystemProviderCapabilities
.
FileOpenReadWriteClose
);
const
resource
=
URI
.
file
(
join
(
testDir
,
'
lorem.txt
'
));
const
content
=
readFileSync
(
resource
.
fsPath
);
const
newContent
=
content
.
toString
()
+
content
.
toString
();
const
fileStat
=
await
service
.
writeFile
(
resource
,
bufferToStream
(
VSBuffer
.
fromString
(
newContent
)));
assert
.
equal
(
fileStat
.
name
,
'
lorem.txt
'
);
assert
.
equal
(
readFileSync
(
resource
.
fsPath
),
newContent
);
});
test
(
'
writeFile (stream) - unbuffered
'
,
async
()
=>
{
setCapabilities
(
fileProvider
,
FileSystemProviderCapabilities
.
FileReadWrite
);
const
resource
=
URI
.
file
(
join
(
testDir
,
'
small.txt
'
));
const
content
=
readFileSync
(
resource
.
fsPath
);
assert
.
equal
(
content
,
'
Small File
'
);
const
newContent
=
'
Updates to the small file
'
;
await
service
.
writeFile
(
resource
,
bufferToStream
(
VSBuffer
.
fromString
(
newContent
)));
assert
.
equal
(
readFileSync
(
resource
.
fsPath
),
newContent
);
});
test
(
'
writeFile (large file - stream) - unbuffered
'
,
async
()
=>
{
setCapabilities
(
fileProvider
,
FileSystemProviderCapabilities
.
FileReadWrite
);
const
resource
=
URI
.
file
(
join
(
testDir
,
'
lorem.txt
'
));
const
content
=
readFileSync
(
resource
.
fsPath
);
const
newContent
=
content
.
toString
()
+
content
.
toString
();
const
fileStat
=
await
service
.
writeFile
(
resource
,
bufferToStream
(
VSBuffer
.
fromString
(
newContent
)));
assert
.
equal
(
fileStat
.
name
,
'
lorem.txt
'
);
assert
.
equal
(
readFileSync
(
resource
.
fsPath
),
newContent
);
});
test
(
'
writeFile (file is created including parents)
'
,
async
()
=>
{
const
resource
=
URI
.
file
(
join
(
testDir
,
'
other
'
,
'
newfile.txt
'
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录