@@ -23,6 +23,8 @@ internal abstract class WindowsFileStreamStrategy : FileStreamStrategy
23
23
/// <summary>Whether the file is opened for reading, writing, or both.</summary>
24
24
private readonly FileAccess _access ;
25
25
26
+ private readonly FileShare _share ;
27
+
26
28
/// <summary>The path to the opened file.</summary>
27
29
protected readonly string ? _path ;
28
30
@@ -32,6 +34,7 @@ internal abstract class WindowsFileStreamStrategy : FileStreamStrategy
32
34
private readonly bool _isPipe ; // Whether to disable async buffering code.
33
35
34
36
private long _appendStart ; // When appending, prevent overwriting file.
37
+ private long ? _length ;
35
38
36
39
internal WindowsFileStreamStrategy ( SafeFileHandle handle , FileAccess access )
37
40
{
@@ -40,6 +43,7 @@ internal WindowsFileStreamStrategy(SafeFileHandle handle, FileAccess access)
40
43
// Note: Cleaner to set the following fields in ValidateAndInitFromHandle,
41
44
// but we can't as they're readonly.
42
45
_access = access ;
46
+ _share = FileStream . DefaultShare ;
43
47
44
48
// As the handle was passed in, we must set the handle field at the very end to
45
49
// avoid the finalizer closing the handle when we throw errors.
@@ -52,6 +56,7 @@ internal WindowsFileStreamStrategy(string path, FileMode mode, FileAccess access
52
56
53
57
_path = fullPath ;
54
58
_access = access ;
59
+ _share = share ;
55
60
56
61
_fileHandle = FileStreamHelpers . OpenHandle ( fullPath , mode , access , share , options ) ;
57
62
@@ -77,7 +82,25 @@ internal WindowsFileStreamStrategy(string path, FileMode mode, FileAccess access
77
82
78
83
public sealed override bool CanWrite => ! _fileHandle . IsClosed && ( _access & FileAccess . Write ) != 0 ;
79
84
80
- public unsafe sealed override long Length => FileStreamHelpers . GetFileLength ( _fileHandle , _path ) ;
85
+ public unsafe sealed override long Length => _share > FileShare . Read ?
86
+ FileStreamHelpers . GetFileLength ( _fileHandle , _path ) :
87
+ _length ??= FileStreamHelpers . GetFileLength ( _fileHandle , _path ) ;
88
+
89
+ protected void UpdateLengthOnChangePosition ( )
90
+ {
91
+ // Do not update the cached length if the file can be written somewhere else
92
+ // or if the length has not been queried.
93
+ if ( _share > FileShare . Read || _length is null )
94
+ {
95
+ Debug . Assert ( _length is null ) ;
96
+ return ;
97
+ }
98
+
99
+ if ( _filePosition > _length )
100
+ {
101
+ _length = _filePosition ;
102
+ }
103
+ }
81
104
82
105
/// <summary>Gets or sets the position within the current stream</summary>
83
106
public override long Position
@@ -256,6 +279,7 @@ protected unsafe void SetLengthCore(long value)
256
279
Debug . Assert ( value >= 0 , "value >= 0" ) ;
257
280
258
281
FileStreamHelpers . SetLength ( _fileHandle , _path , value ) ;
282
+ _length = value ;
259
283
260
284
if ( _filePosition > value )
261
285
{
0 commit comments