Skip to content

Commit ec701cf

Browse files
fix: added stateful tracking of unshared file streams and prevented multiple openings
1 parent 2739e85 commit ec701cf

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileStream.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Threading;
33
using System.Runtime.Versioning;
44
using System.Security.AccessControl;
5+
using System.Collections.Generic;
56

67
namespace System.IO.Abstractions.TestingHelpers;
78

@@ -32,16 +33,19 @@ public NullFileSystemStream() : base(Null, ".", true)
3233
private readonly IMockFileDataAccessor mockFileDataAccessor;
3334
private readonly string path;
3435
private readonly FileAccess access = FileAccess.ReadWrite;
36+
private readonly FileShare share = FileShare.Read;
3537
private readonly FileOptions options;
3638
private readonly MockFileData fileData;
3739
private bool disposed;
40+
private static HashSet<string> _fileShareNoneStreams = [];
3841

3942
/// <inheritdoc />
4043
public MockFileStream(
4144
IMockFileDataAccessor mockFileDataAccessor,
4245
string path,
4346
FileMode mode,
4447
FileAccess access = FileAccess.ReadWrite,
48+
FileShare share = FileShare.Read,
4549
FileOptions options = FileOptions.None)
4650
: base(new MemoryStream(),
4751
path == null ? null : Path.GetFullPath(path),
@@ -54,6 +58,11 @@ public MockFileStream(
5458
this.path = path;
5559
this.options = options;
5660

61+
if (_fileShareNoneStreams.Contains(path))
62+
{
63+
throw new IOException($"The process cannot access the file '{path}' because it is being used by another process.");
64+
}
65+
5766
if (mockFileDataAccessor.FileExists(path))
5867
{
5968
if (mode.Equals(FileMode.CreateNew))
@@ -97,7 +106,12 @@ public MockFileStream(
97106
mockFileDataAccessor.AddFile(path, fileData);
98107
}
99108

109+
if (share is FileShare.None)
110+
{
111+
_fileShareNoneStreams.Add(path);
112+
}
100113
this.access = access;
114+
this.share = share;
101115
}
102116

103117
private static void ThrowIfInvalidModeAccess(FileMode mode, FileAccess access)
@@ -144,6 +158,10 @@ protected override void Dispose(bool disposing)
144158
{
145159
return;
146160
}
161+
if (share is FileShare.None)
162+
{
163+
_fileShareNoneStreams.Remove(path);
164+
}
147165
InternalFlush();
148166
base.Dispose(disposing);
149167
OnClose();

0 commit comments

Comments
 (0)