Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b00fed7

Browse files
committed
Eliminate extra IFileSystemObject allocation on Win32 and Unix
FileSystemInfo/FileInfo/DirectoryInfo all carry a IFileSystemObject which is used internally for the actual implementation. While this enables FileSystemInfo/FileInfo/DirectoryInfo to be used with WinRT, it comes with the cost of an extra unnecessary allocation for plain Win32 and Unix. This change eliminates the allocation on Win32 and Unix. After this change, the extra object allocation only happens when the WinRT APIs need to be used.
1 parent 24820ce commit b00fed7

15 files changed

+433
-384
lines changed

src/Common/src/Interop/Windows/mincore/Interop.GetFileAttributesEx.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal struct WIN32_FILE_ATTRIBUTE_DATA
3030
internal uint fileSizeHigh;
3131
internal uint fileSizeLow;
3232

33-
internal void PopulateFrom(WIN32_FIND_DATA findData)
33+
internal void PopulateFrom(ref WIN32_FIND_DATA findData)
3434
{
3535
// Copy the information to data
3636
fileAttributes = (int)findData.dwFileAttributes;

src/System.IO.FileSystem/src/System.IO.FileSystem.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
5858
<Compile Include="Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
5959
<Compile Include="Microsoft\Win32\SafeHandles\SafeFindHandle.Windows.cs" />
60+
<Compile Include="System\IO\DirectoryInfo.Windows.cs" />
61+
<Compile Include="System\IO\FileInfo.Windows.cs" />
6062
<Compile Include="System\IO\FileStream.Win32.cs" />
6163
<Compile Include="System\IO\FileSystemInfo.Windows.cs" />
6264
<Compile Include="System\IO\PathHelpers.Windows.cs" />
@@ -191,6 +193,7 @@
191193
<Link>Common\Interop\Windows\Interop.CopyFile.cs</Link>
192194
</Compile>
193195
<Compile Include="System\IO\FileSystem.Current.Win32.cs" />
196+
<Compile Include="System\IO\FileSystemInfo.Win32.cs" />
194197
<Compile Include="$(CommonPath)\Interop\Windows\mincore\Interop.CreateFile.cs">
195198
<Link>Common\Interop\Windows\Interop.CreateFile.cs</Link>
196199
</Compile>
@@ -219,6 +222,7 @@
219222
<Link>Common\Interop\Windows\WinRT\Interop.SetErrorMode.cs</Link>
220223
</Compile>
221224
<Compile Include="System\IO\FileSystem.Current.MuxWin32WinRT.cs" />
225+
<Compile Include="System\IO\FileSystemInfo.WinRT.cs" />
222226
<Compile Include="System\IO\MultiplexingWin32WinRTFileSystem.cs" />
223227
<Compile Include="System\IO\WinRTIOExtensions.cs" />
224228
<Compile Include="System\IO\WinRTFileStream.cs" />
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Diagnostics;
5+
using System.Security;
6+
7+
namespace System.IO
8+
{
9+
partial class DirectoryInfo
10+
{
11+
[SecurityCritical]
12+
internal DirectoryInfo(string fullPath, ref Interop.mincore.WIN32_FIND_DATA findData)
13+
: this(fullPath, findData.cFileName)
14+
{
15+
Debug.Assert(string.Equals(findData.cFileName, Path.GetFileName(fullPath), StringComparison.Ordinal));
16+
Init(ref findData);
17+
}
18+
}
19+
}

src/System.IO.FileSystem/src/System/IO/DirectoryInfo.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace System.IO
1010
{
11-
public sealed class DirectoryInfo : FileSystemInfo
11+
public sealed partial class DirectoryInfo : FileSystemInfo
1212
{
1313
[System.Security.SecuritySafeCritical]
1414
public DirectoryInfo(String path)
@@ -23,12 +23,12 @@ public DirectoryInfo(String path)
2323
}
2424

2525
[System.Security.SecuritySafeCritical]
26-
internal DirectoryInfo(String fullPath, IFileSystemObject fileSystemObject) : base(fileSystemObject)
26+
internal DirectoryInfo(String fullPath, String originalPath)
2727
{
28-
Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
29-
28+
Debug.Assert(Path.IsPathRooted(fullPath), "fullPath must be fully qualified!");
29+
3030
// Fast path when we know a DirectoryInfo exists.
31-
OriginalPath = Path.GetFileName(fullPath);
31+
OriginalPath = originalPath ?? Path.GetFileName(fullPath);
3232
FullPath = fullPath;
3333
DisplayPath = GetDisplayName(OriginalPath, FullPath);
3434
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Diagnostics;
5+
using System.Security;
6+
7+
namespace System.IO
8+
{
9+
partial class FileInfo
10+
{
11+
[SecurityCritical]
12+
internal FileInfo(string fullPath, ref Interop.mincore.WIN32_FIND_DATA findData)
13+
: this(fullPath, findData.cFileName)
14+
{
15+
Debug.Assert(string.Equals(findData.cFileName, Path.GetFileName(fullPath), StringComparison.Ordinal));
16+
Init(ref findData);
17+
}
18+
}
19+
}

src/System.IO.FileSystem/src/System/IO/FileInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace System.IO
1313
{
1414
// Class for creating FileStream objects, and some basic file management
1515
// routines such as Delete, etc.
16-
public sealed class FileInfo : FileSystemInfo
16+
public sealed partial class FileInfo : FileSystemInfo
1717
{
1818
private String _name;
1919

@@ -48,10 +48,10 @@ private String GetDisplayPath(String originalPath)
4848
}
4949

5050
[System.Security.SecuritySafeCritical]
51-
internal FileInfo(String fullPath, IFileSystemObject fileSystemObject) : base(fileSystemObject)
51+
internal FileInfo(String fullPath, String originalPath)
5252
{
5353
Debug.Assert(Path.IsPathRooted(fullPath), "fullPath must be fully qualified!");
54-
_name = Path.GetFileName(fullPath);
54+
_name = originalPath ?? Path.GetFileName(fullPath);
5555
OriginalPath = _name;
5656
FullPath = fullPath;
5757
DisplayPath = _name;

0 commit comments

Comments
 (0)