Skip to content

Commit ebb1167

Browse files
authored
Legacy FileStream mode and symlink breaking changes (#31602)
1 parent 3380a4c commit ebb1167

File tree

6 files changed

+242
-26
lines changed

6 files changed

+242
-26
lines changed

docs/core/compatibility/7.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ If you're migrating an app to .NET 7, the breaking changes listed here might aff
4545
| [Collectible Assembly in non-collectible AssemblyLoadContext](core-libraries/7.0/collectible-assemblies.md) || ✔️ | Preview 5 |
4646
| [Equals method behavior change for NaN](core-libraries/7.0/equals-nan.md) || ✔️ | Preview 5 |
4747
| [Generic type constraint on PatternContext\<T>](core-libraries/7.0/patterncontext-generic-constraint.md) ||| Preview 3 |
48+
| [Legacy FileStream strategy removed](core-libraries/7.0/filestream-compat-switch.md) || ✔️ | Preview 1 |
4849
| [Library support for older frameworks](core-libraries/7.0/old-framework-support.md) ||| Preview 1 |
4950
| [Maximum precision for numeric format strings](core-libraries/7.0/max-precision-numeric-format-strings.md) || ✔️ | RC 1 |
5051
| [SerializationFormat.Binary is obsolete](core-libraries/7.0/serializationformat-binary.md) ||| Preview 2 |
52+
| [Time fields on symbolic links](core-libraries/7.0/symbolic-link-timestamps.md) || ✔️ | Preview 1 |
5153
| [Tracking linked cache entries](core-libraries/7.0/memorycache-tracking.md) || ✔️ | Preview 1 |
5254
| [Validate CompressionLevel for BrotliStream](core-libraries/7.0/compressionlevel-validation.md) || ✔️ | Preview 1 |
5355

docs/core/compatibility/core-libraries/6.0/filestream-doesnt-sync-offset-with-os.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ".NET 6 breaking change: FileStream doesn't synchronize file offset with OS"
33
description: Learn about the .NET 6 breaking change in core .NET libraries where FileStream doesn't synchronize the file offset with the operating system.
4-
ms.date: 05/05/2021
4+
ms.date: 10/04/2022
55
---
66
# FileStream no longer synchronizes file offset with OS
77

@@ -65,6 +65,9 @@ With this change, <xref:System.IO.FileStream.ReadAsync%2A> operations are up to
6565
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
6666
```
6767

68+
> [!NOTE]
69+
> This switch is only available in .NET 6. It was [removed in .NET 7](../7.0/filestream-compat-switch.md).
70+
6871
## Affected APIs
6972

7073
None.
@@ -73,15 +76,3 @@ None.
7376

7477
- [SetFilePointer function](/windows/win32/api/fileapi/nf-fileapi-setfilepointer)
7578
- [SetFilePointerEx function](/windows/win32/api/fileapi/nf-fileapi-setfilepointerex)
76-
77-
<!--
78-
79-
### Category
80-
81-
- Core .NET libraries
82-
83-
### Affected APIs
84-
85-
Not detectible via API analysis.
86-
87-
-->

docs/core/compatibility/core-libraries/6.0/filestream-position-updates-after-readasync-writeasync-completion.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ".NET 6 breaking change: FileStream.Position updated after ReadAsync or WriteAsync completion"
33
description: Learn about the .NET 6 breaking change in core .NET libraries where FileStream.Position is updated after ReadAsync or WriteAsync completion.
4-
ms.date: 05/05/2021
4+
ms.date: 10/04/2022
55
---
66
# FileStream.Position updates after ReadAsync or WriteAsync completes
77

@@ -68,18 +68,9 @@ Now, when buffering is enabled (that is, the `bufferSize` argument that's passed
6868
set DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM=1
6969
```
7070

71+
> [!NOTE]
72+
> This switch is only available in .NET 6. It was [removed in .NET 7](../7.0/filestream-compat-switch.md).
73+
7174
## Affected APIs
7275

7376
- <xref:System.IO.FileStream.Position?displayProperty=fullName>
74-
75-
<!--
76-
77-
### Category
78-
79-
- Core .NET libraries
80-
81-
### Affected APIs
82-
83-
- `P:System.IO.FileStream.Position`
84-
85-
-->
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: ".NET 7 breaking change: Legacy FileStream strategy removed"
3+
description: Learn about the .NET 7 breaking change in core .NET libraries where the the ability to use the legacy `FileStream` implementation has been removed.
4+
ms.date: 10/04/2022
5+
---
6+
# Legacy FileStream strategy removed
7+
8+
The `AppContext` switch `System.IO.UseNet5CompatFileStream` and the ability to use the legacy <xref:System.IO.FileStream> implementation were removed.
9+
10+
## Previous behavior
11+
12+
The legacy `FileStream` implementation was available and you could opt into it by using the `UseNet5CompatFileStream` switch or the `DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM` environment variable.
13+
14+
## New behavior
15+
16+
Starting in .NET 7, you can no longer opt in to use the legacy `FileStream` implementation.
17+
18+
## Version introduced
19+
20+
.NET 7 Preview 1
21+
22+
## Type of breaking change
23+
24+
This change can affect [binary compatibility](../../categories.md#binary-compatibility).
25+
26+
## Reason for change
27+
28+
The `UseNet5CompatFileStream` switch and `DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM` environment variable were included in .NET 6 in case the new implementation caused breaking changes. Any breaking changes have now been fixed. Since there are no more bugs introduced by the `FileStream` changes, the compatibility mode was removed and with it all the legacy code, which makes the codebase easier to maintain.
29+
30+
## Recommended action
31+
32+
If you're currently using the switch (or the `DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM` environment variable) to opt into legacy code and are upgrading to .NET 7, the switch will no longer have any effect and you should remove it.
33+
34+
## Affected APIs
35+
36+
- <xref:System.IO.FileStream?displayProperty=fullName>
37+
- <xref:System.IO.File.Create(System.String)?displayProperty=fullName>
38+
- <xref:System.IO.File.Create(System.String,System.Int32)?displayProperty=fullName>
39+
- <xref:System.IO.File.Create(System.String,System.Int32,System.IO.FileOptions)?displayProperty=fullName>
40+
- <xref:System.IO.File.Create(System.String,System.Int32,System.IO.FileOptions,System.Security.AccessControl.FileSecurity)?displayProperty=fullName>
41+
- <xref:System.IO.File.Open(System.String,System.IO.FileMode)?displayProperty=fullName>
42+
- <xref:System.IO.File.Open(System.String,System.IO.FileStreamOptions)?displayProperty=fullName>
43+
- <xref:System.IO.File.Open(System.String,System.IO.FileMode,System.IO.FileAccess)?displayProperty=fullName>
44+
- <xref:System.IO.File.Open(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)?displayProperty=fullName>
45+
- <xref:System.IO.File.OpenRead(System.String)?displayProperty=fullName>
46+
- <xref:System.IO.File.OpenWrite(System.String)?displayProperty=fullName>
47+
- <xref:System.IO.FileSystemAclExtensions.Create(System.IO.FileInfo,System.IO.FileMode,System.Security.AccessControl.FileSystemRights,System.IO.FileShare,System.Int32,System.IO.FileOptions,System.Security.AccessControl.FileSecurity)?displayProperty=fullName>
48+
- <xref:System.IO.FileInfo.Create?displayProperty=fullName>
49+
- <xref:System.IO.FileInfo.Open%2A?displayProperty=fullName>
50+
- <xref:System.IO.FileInfo.OpenRead?displayProperty=fullName>
51+
- <xref:System.IO.FileInfo.OpenWrite?displayProperty=fullName>
52+
53+
## See also
54+
55+
- [FileStream no longer synchronizes file offset with OS (.NET 6)](../6.0/filestream-doesnt-sync-offset-with-os.md)
56+
- [FileStream.Position updates after ReadAsync or WriteAsync completes (.NET 6)](../6.0/filestream-position-updates-after-readasync-writeasync-completion.md)
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
title: ".NET 7 breaking change: Time fields on symbolic links"
3+
description: Learn about the .NET 7 breaking change in core .NET libraries where updating CreationTime[Utc], LastAccessTime[Utc], and LastWriteTime[Utc] on a symbolic link no longer affects the target .
4+
ms.date: 10/04/2022
5+
---
6+
# Time fields on symbolic links
7+
8+
When changes are made to the following time-related fields on a symbolic link ("symlink"), the updates now affect the symlink itself and not the target:
9+
10+
- <xref:System.IO.FileSystemInfo.CreationTime>
11+
- <xref:System.IO.FileSystemInfo.CreationTimeUtc>
12+
- <xref:System.IO.FileSystemInfo.LastAccessTime>
13+
- <xref:System.IO.FileSystemInfo.LastAccessTimeUtc>
14+
- <xref:System.IO.FileSystemInfo.LastWriteTime>
15+
- <xref:System.IO.FileSystemInfo.LastWriteTimeUtc>
16+
17+
## Previous behavior
18+
19+
Previously, updating any of the time-related fields on a symlink affected the fields of the symlink's target.
20+
21+
Consider the following program that prints the various time field values on a file and its symbolic link, updates the symlink's time field values to 1 day later, and then reprints the time field values on both the file and symlink.
22+
23+
```csharp
24+
string filename = "file";
25+
string linkname = "link";
26+
27+
// Create a file and symlink.
28+
File.Create(filename).Dispose();
29+
File.CreateSymbolicLink(linkname, filename);
30+
31+
Console.WriteLine("Before update:");
32+
PrintMetadata(filename);
33+
PrintMetadata(linkname);
34+
35+
UpdateMetadata(linkname);
36+
37+
Console.WriteLine("\nAfter update:");
38+
PrintMetadata(filename);
39+
PrintMetadata(linkname);
40+
41+
static void UpdateMetadata(string filename)
42+
{
43+
DateTime tomorrow = DateTime.Now.AddDays(1);
44+
45+
File.SetCreationTime(filename, tomorrow);
46+
File.SetLastAccessTime(filename, tomorrow);
47+
File.SetLastWriteTime(filename, tomorrow);
48+
File.SetAttributes(filename, File.GetAttributes(filename) | FileAttributes.Offline);
49+
}
50+
51+
static void PrintMetadata(string filename)
52+
{
53+
Console.WriteLine($"---{filename}---");
54+
Console.WriteLine("Creation:\t" + File.GetCreationTime(filename));
55+
Console.WriteLine("Last access:\t" + File.GetLastAccessTime(filename));
56+
Console.WriteLine("Last write:\t" + File.GetLastWriteTime(filename));
57+
Console.WriteLine("Attributes:\t" + File.GetAttributes(filename));
58+
}
59+
```
60+
61+
Previously, after updating the values on the symlink, only the target file's time fields were updated. The output of the preceding program was as follows:
62+
63+
```output
64+
Before update:
65+
---file---
66+
Creation: 9/29/2022 10:35:40 AM
67+
Last access: 9/29/2022 10:35:40 AM
68+
Last write: 9/29/2022 10:35:40 AM
69+
Attributes: Archive
70+
---link---
71+
Creation: 9/29/2022 10:35:40 AM
72+
Last access: 9/29/2022 10:35:40 AM
73+
Last write: 9/29/2022 10:35:40 AM
74+
Attributes: Archive, ReparsePoint
75+
76+
After update:
77+
---file---
78+
Creation: 9/30/2022 10:35:40 AM
79+
Last access: 9/30/2022 10:35:40 AM
80+
Last write: 9/30/2022 10:35:40 AM
81+
Attributes: Archive
82+
---link---
83+
Creation: 9/29/2022 10:35:40 AM
84+
Last access: 9/29/2022 10:35:40 AM
85+
Last write: 9/29/2022 10:35:40 AM
86+
Attributes: Archive, ReparsePoint, Offline
87+
```
88+
89+
## New behavior
90+
91+
Starting in .NET 7, updating any of the time-related fields on a symlink affects the fields of the symlink itself and not the target file.
92+
93+
The output of the program shown in the [Previous behavior](#previous-behavior) section is as follows:
94+
95+
```output
96+
Before update:
97+
---file---
98+
Creation: 9/29/2022 10:33:39 AM
99+
Last access: 9/29/2022 10:33:39 AM
100+
Last write: 9/29/2022 10:33:39 AM
101+
Attributes: Archive
102+
---link---
103+
Creation: 9/29/2022 10:33:39 AM
104+
Last access: 9/29/2022 10:33:39 AM
105+
Last write: 9/29/2022 10:33:39 AM
106+
Attributes: Archive, ReparsePoint
107+
108+
After update:
109+
---file---
110+
Creation: 9/29/2022 10:33:39 AM
111+
Last access: 9/29/2022 10:33:39 AM
112+
Last write: 9/29/2022 10:33:39 AM
113+
Attributes: Archive
114+
---link---
115+
Creation: 9/30/2022 10:33:39 AM
116+
Last access: 9/30/2022 10:33:39 AM
117+
Last write: 9/30/2022 10:33:39 AM
118+
Attributes: Archive, ReparsePoint, Offline
119+
```
120+
121+
## Version introduced
122+
123+
.NET 7 Preview 1
124+
125+
## Type of breaking change
126+
127+
This change can affect [binary compatibility](../../categories.md#binary-compatibility).
128+
129+
## Reason for change
130+
131+
The previous behavior was unexpected and undesirable in some cases:
132+
133+
- It was inconsistent with the behavior of the properties and methods that get the same fields.
134+
- It was also impossible to actually update the fields in the symlink itself using .NET APIs.
135+
136+
## Recommended action
137+
138+
If you were relying on this behavior to set values on the symlink's target, setting one of the `*Time` fields in a symlink will no longer affect the target. You can use the new symbolic link APIs to obtain the target of a symlink and then update that file system object instead.
139+
140+
```csharp
141+
FileSystemInfo? targetInfo = linkInfo.ResolveLinkTarget(returnFinalTarget: true);
142+
if (targetInfo != null)
143+
{
144+
// Update the properties accordingly.
145+
targetInfo.LastWriteTime = DateTime.Now;
146+
}
147+
```
148+
149+
## Affected APIs
150+
151+
- <xref:System.IO.Directory.SetCreationTime(System.String,System.DateTime)?displayProperty=fullName>
152+
- <xref:System.IO.Directory.SetCreationTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
153+
- <xref:System.IO.Directory.SetLastAccessTime(System.String,System.DateTime)?displayProperty=fullName>
154+
- <xref:System.IO.Directory.SetLastAccessTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
155+
- <xref:System.IO.Directory.SetLastWriteTime(System.String,System.DateTime)?displayProperty=fullName>
156+
- <xref:System.IO.Directory.SetLastWriteTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
157+
- <xref:System.IO.File.SetCreationTime(System.String,System.DateTime)?displayProperty=fullName>
158+
- <xref:System.IO.File.SetCreationTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
159+
- <xref:System.IO.File.SetLastAccessTime(System.String,System.DateTime)?displayProperty=fullName>
160+
- <xref:System.IO.File.SetLastAccessTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
161+
- <xref:System.IO.File.SetLastWriteTime(System.String,System.DateTime)?displayProperty=fullName>
162+
- <xref:System.IO.File.SetLastWriteTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
163+
- <xref:System.IO.FileSystemInfo.CreationTime?displayProperty=fullName>
164+
- <xref:System.IO.FileSystemInfo.CreationTimeUtc?displayProperty=fullName>
165+
- <xref:System.IO.FileSystemInfo.LastAccessTime?displayProperty=fullName>
166+
- <xref:System.IO.FileSystemInfo.LastAccessTimeUtc?displayProperty=fullName>
167+
- <xref:System.IO.FileSystemInfo.LastWriteTime?displayProperty=fullName>
168+
- <xref:System.IO.FileSystemInfo.LastWriteTimeUtc?displayProperty=fullName>

docs/core/compatibility/toc.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ items:
6969
href: core-libraries/7.0/equals-nan.md
7070
- name: Generic type constraint on PatternContext<T>
7171
href: core-libraries/7.0/patterncontext-generic-constraint.md
72+
- name: Legacy FileStream strategy removed
73+
href: core-libraries/7.0/filestream-compat-switch.md
7274
- name: Library support for older frameworks
7375
href: core-libraries/7.0/old-framework-support.md
7476
- name: Maximum precision for numeric format strings
@@ -77,6 +79,8 @@ items:
7779
href: core-libraries/7.0/reflection-invoke-exceptions.md
7880
- name: SerializationFormat.Binary is obsolete
7981
href: core-libraries/7.0/serializationformat-binary.md
82+
- name: Time fields on symbolic links
83+
href: core-libraries/7.0/symbolic-link-timestamps.md
8084
- name: Tracking linked cache entries
8185
href: core-libraries/7.0/memorycache-tracking.md
8286
- name: Validate CompressionLevel for BrotliStream
@@ -849,6 +853,8 @@ items:
849853
href: core-libraries/7.0/equals-nan.md
850854
- name: Generic type constraint on PatternContext<T>
851855
href: core-libraries/7.0/patterncontext-generic-constraint.md
856+
- name: Legacy FileStream strategy removed
857+
href: core-libraries/7.0/filestream-compat-switch.md
852858
- name: Library support for older frameworks
853859
href: core-libraries/7.0/old-framework-support.md
854860
- name: Maximum precision for numeric format strings
@@ -857,6 +863,8 @@ items:
857863
href: core-libraries/7.0/reflection-invoke-exceptions.md
858864
- name: SerializationFormat.Binary is obsolete
859865
href: core-libraries/7.0/serializationformat-binary.md
866+
- name: Time fields on symbolic links
867+
href: core-libraries/7.0/symbolic-link-timestamps.md
860868
- name: Tracking linked cache entries
861869
href: core-libraries/7.0/memorycache-tracking.md
862870
- name: Validate CompressionLevel for BrotliStream

0 commit comments

Comments
 (0)