Skip to content

Commit

Permalink
Add FileStreamOptions overloads (#52720)
Browse files Browse the repository at this point in the history
  • Loading branch information
manandre authored Jun 10, 2021
1 parent b7f7762 commit 8538436
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 16 deletions.
36 changes: 36 additions & 0 deletions src/libraries/System.IO.FileSystem/tests/File/Open.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,42 @@ protected override FileStream CreateFileStream(string path, FileMode mode, FileA
}
}

public class File_Open_str_options_as : FileStream_ctor_options_as
{
protected override FileStream CreateFileStream(string path, FileMode mode)
{
return File.Open(path,
new FileStreamOptions {
Mode = mode,
Access = mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite,
PreallocationSize = PreallocationSize
});
}

protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access)
{
return File.Open(path,
new FileStreamOptions {
Mode = mode,
Access = access,
PreallocationSize = PreallocationSize
});
}

protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
return File.Open(path,
new FileStreamOptions {
Mode = mode,
Access = access,
Share = share,
Options = options,
BufferSize = bufferSize,
PreallocationSize = PreallocationSize
});
}
}

public class File_OpenSpecial : FileStream_ctor_str_fm_fa_fs
{
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access)
Expand Down
36 changes: 36 additions & 0 deletions src/libraries/System.IO.FileSystem/tests/FileInfo/Open.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,42 @@ protected override FileStream CreateFileStream(string path, FileMode mode, FileA
}
}

public class FileInfo_Open_options_as : FileStream_ctor_options_as
{
protected override FileStream CreateFileStream(string path, FileMode mode)
{
return new FileInfo(path).Open(
new FileStreamOptions {
Mode = mode,
Access = mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite,
PreallocationSize = PreallocationSize
});
}

protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access)
{
return new FileInfo(path).Open(
new FileStreamOptions {
Mode = mode,
Access = access,
PreallocationSize = PreallocationSize
});
}

protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
return new FileInfo(path).Open(
new FileStreamOptions {
Mode = mode,
Access = access,
Share = share,
Options = options,
BufferSize = bufferSize,
PreallocationSize = PreallocationSize
});
}
}

public class FileInfo_OpenSpecial : FileStream_ctor_str_fm_fa_fs
{
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,29 @@ public class StreamReader_StringCtorTests
public static void NullArgs_ThrowsArgumentNullException()
{
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, (FileStreamOptions)null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, (Encoding)null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, null, true));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, null, true, null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamReader((string)null, null, true, -1));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamReader("", null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamReader("", (Encoding)null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamReader("", null, true));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamReader("", null, true, null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamReader("", null, true, -1));
AssertExtensions.Throws<ArgumentNullException>("options", () => new StreamReader("path", (FileStreamOptions)null));
AssertExtensions.Throws<ArgumentNullException>("options", () => new StreamReader("path", Encoding.UTF8, true, null));

}

[Fact]
public static void EmptyPath_ThrowsArgumentException()
{
// No argument name for the empty path exception
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader(""));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader("", new FileStreamOptions()));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader("", Encoding.UTF8));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader("", Encoding.UTF8, true));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader("", Encoding.UTF8, true, new FileStreamOptions()));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamReader("", Encoding.UTF8, true, -1));
}

Expand Down
25 changes: 25 additions & 0 deletions src/libraries/System.IO/tests/StreamReader/StreamReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,30 @@ public void DetectEncoding_EncodingRoundtrips(Encoding encoding)
Assert.Equal(encoding.EncodingName, reader.CurrentEncoding.EncodingName);
}
}

[Theory]
[MemberData(nameof(DetectEncoding_EncodingRoundtrips_MemberData))]
public void DetectEncoding_EncodingRoundtrips_Path(Encoding encoding)
{
const string Text = "This is some text for testing.";
string path = GetTestFilePath();

using (var writer = new StreamWriter(path, false, encoding))
{
writer.Write(Text);
}

using (var reader = new StreamReader(path, detectEncodingFromByteOrderMarks: true))
{
Assert.Equal(Text, reader.ReadToEnd());
Assert.Equal(encoding.EncodingName, reader.CurrentEncoding.EncodingName);
}

using (var reader = new StreamReader(path, encoding))
{
Assert.Equal(Text, reader.ReadToEnd());
Assert.Equal(encoding.EncodingName, reader.CurrentEncoding.EncodingName);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ public class StreamWriter_StringCtorTests
public static void NullArgs_ThrowsArgumentNullException()
{
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamWriter((string)null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamWriter((string)null, null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamWriter((string)null, true));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamWriter((string)null, true, null));
AssertExtensions.Throws<ArgumentNullException>("path", () => new StreamWriter((string)null, true, null, -1));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("path", true, null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("path", null, null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("path", true, null, -1));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("", true, null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("", null, null));
AssertExtensions.Throws<ArgumentNullException>("encoding", () => new StreamWriter("", true, null, -1));
}

Expand All @@ -29,8 +32,10 @@ public static void EmptyPath_ThrowsArgumentException()
{
// No argument name for the empty path exception
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter(""));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter("", new FileStreamOptions()));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter("", true));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter("", true, Encoding.UTF8));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter("", Encoding.UTF8, new FileStreamOptions()));
AssertExtensions.Throws<ArgumentException>(null, () => new StreamWriter("", true, Encoding.UTF8, -1));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,11 @@
<Compile Include="$(MSBuildThisFileDirectory)System\IO\EnumerationOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\EndOfStreamException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\File.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\File.netcoreapp.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileAccess.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileAttributes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileInfo.netcoreapp.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileLoadException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileNotFoundException.cs" />
Expand Down
5 changes: 2 additions & 3 deletions src/libraries/System.Private.CoreLib/src/System/IO/File.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace System.IO
{
// Class for creating FileStream objects, and some basic file management
// routines such as Delete, etc.
public static class File
public static partial class File
{
// Don't use Array.MaxLength. MS.IO.Redist targets .NET Framework.
private const int MaxByteArrayLength = 0x7FFFFFC7;
Expand Down Expand Up @@ -263,8 +263,7 @@ public static FileStream OpenRead(string path)

public static FileStream OpenWrite(string path)
{
return new FileStream(path, FileMode.OpenOrCreate,
FileAccess.Write, FileShare.None);
return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
}

public static string ReadAllText(string path)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.IO
{
public static partial class File
{
/// <summary>
/// Initializes a new instance of the <see cref="System.IO.FileStream" /> class with the specified path, creation mode, read/write and sharing permission, the access other FileStreams can have to the same file, the buffer size, additional file options and the allocation size.
/// </summary>
/// <remarks><see cref="System.IO.FileStream(string,System.IO.FileStreamOptions)"/> for information about exceptions.</remarks>
public static FileStream Open(string path, FileStreamOptions options) => new FileStream(path, options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public FileStream Open(FileMode mode, FileAccess access, FileShare share)
=> new FileStream(NormalizedPath, mode, access, share);

public FileStream OpenRead()
=> new FileStream(NormalizedPath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
=> new FileStream(NormalizedPath, FileMode.Open, FileAccess.Read, FileShare.Read, File.DefaultBufferSize, false);

public FileStream OpenWrite()
=> new FileStream(NormalizedPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.IO
{
public sealed partial class FileInfo : FileSystemInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="System.IO.FileStream" /> class with the specified creation mode, read/write and sharing permission, the access other FileStreams can have to the same file, the buffer size, additional file options and the allocation size.
/// </summary>
/// <remarks><see cref="System.IO.FileStream(string,System.IO.FileStreamOptions)"/> for information about exceptions.</remarks>
public FileStream Open(FileStreamOptions options) => File.Open(NormalizedPath, options);
}
}
36 changes: 30 additions & 6 deletions src/libraries/System.Private.CoreLib/src/System/IO/StreamReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,23 +193,47 @@ public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteO
{
}

public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize) :
this(ValidateArgsAndOpenPath(path, encoding, bufferSize), encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen: false)
public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
: this(ValidateArgsAndOpenPath(path, encoding, bufferSize), encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen: false)
{
}

public StreamReader(string path, FileStreamOptions options)
: this(path, Encoding.UTF8, true, options)
{
}

public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, FileStreamOptions options)
: this(ValidateArgsAndOpenPath(path, encoding, options), encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize)
{
}

private static Stream ValidateArgsAndOpenPath(string path, Encoding encoding, FileStreamOptions options)
{
ValidateArgs(path, encoding);
if (options == null)
throw new ArgumentNullException(nameof(options));

return new FileStream(path, options);
}

private static Stream ValidateArgsAndOpenPath(string path, Encoding encoding, int bufferSize)
{
ValidateArgs(path, encoding);
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);

return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize);
}

private static void ValidateArgs(string path, Encoding encoding)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
if (encoding == null)
throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(SR.Argument_EmptyPath);
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);

return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan);
}

public override void Close()
Expand Down
32 changes: 28 additions & 4 deletions src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,42 @@ public StreamWriter(string path, bool append, Encoding encoding, int bufferSize)
{
}

public StreamWriter(string path, FileStreamOptions options)
: this(path, UTF8NoBOM, options)
{
}

public StreamWriter(string path, Encoding encoding, FileStreamOptions options)
: this(ValidateArgsAndOpenPath(path, encoding, options), encoding, DefaultFileStreamBufferSize)
{
}

private static Stream ValidateArgsAndOpenPath(string path, Encoding encoding, FileStreamOptions options)
{
ValidateArgs(path, encoding);
if (options == null)
throw new ArgumentNullException(nameof(options));

return new FileStream(path, options);
}

private static Stream ValidateArgsAndOpenPath(string path, bool append, Encoding encoding, int bufferSize)
{
ValidateArgs(path, encoding);
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);

return new FileStream(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.Read, DefaultFileStreamBufferSize);
}

private static void ValidateArgs(string path, Encoding encoding)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
if (encoding == null)
throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(SR.Argument_EmptyPath);
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);

return new FileStream(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan);
}

public override void Close()
Expand Down
Loading

0 comments on commit 8538436

Please sign in to comment.