Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: ".NET 6 breaking change: FileStream doesn't synchronize file offset with OS"
description: Learn about the .NET 6 breaking change in core .NET libraries where FileStream doesn't synchronize the file offset with the operating system.
ms.date: 05/05/2021
ms.date: 10/04/2022
---
# FileStream no longer synchronizes file offset with OS

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

> [!NOTE]
> This switch is only available in .NET 6. It was [removed in .NET 7](../7.0/filestream-compat-switch.md).

## Affected APIs

None.
Expand All @@ -73,15 +76,3 @@ None.

- [SetFilePointer function](/windows/win32/api/fileapi/nf-fileapi-setfilepointer)
- [SetFilePointerEx function](/windows/win32/api/fileapi/nf-fileapi-setfilepointerex)

<!--

### Category

- Core .NET libraries

### Affected APIs

Not detectible via API analysis.

-->
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: ".NET 6 breaking change: FileStream.Position updated after ReadAsync or WriteAsync completion"
description: Learn about the .NET 6 breaking change in core .NET libraries where FileStream.Position is updated after ReadAsync or WriteAsync completion.
ms.date: 05/05/2021
ms.date: 10/04/2022
---
# FileStream.Position updates after ReadAsync or WriteAsync completes

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

> [!NOTE]
> This switch is only available in .NET 6. It was [removed in .NET 7](../7.0/filestream-compat-switch.md).

## Affected APIs

- <xref:System.IO.FileStream.Position?displayProperty=fullName>

<!--

### Category

- Core .NET libraries

### Affected APIs

- `P:System.IO.FileStream.Position`

-->
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: ".NET 7 breaking change: Legacy FileStream strategy removed"
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.
ms.date: 10/04/2022
---
# Legacy FileStream strategy removed

The `AppContext` switch `System.IO.UseNet5CompatFileStream` and the ability to use the legacy <xref:System.IO.FileStream> implementation were removed.

## Previous behavior

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.

## New behavior

Starting in .NET 7, you can no longer opt in to use the legacy `FileStream` implementation.

## Version introduced

.NET 7 Preview 1

## Type of breaking change

This change can affect [binary compatibility](../../categories.md#binary-compatibility).

## Reason for change

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.

## Recommended action

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.

## Affected APIs

- <xref:System.IO.FileStream?displayProperty=fullName>
- <xref:System.IO.File.Create(System.String)?displayProperty=fullName>
- <xref:System.IO.File.Create(System.String,System.Int32)?displayProperty=fullName>
- <xref:System.IO.File.Create(System.String,System.Int32,System.IO.FileOptions)?displayProperty=fullName>
- <xref:System.IO.File.Create(System.String,System.Int32,System.IO.FileOptions,System.Security.AccessControl.FileSecurity)?displayProperty=fullName>
- <xref:System.IO.File.Open(System.String,System.IO.FileMode)?displayProperty=fullName>
- <xref:System.IO.File.Open(System.String,System.IO.FileStreamOptions)?displayProperty=fullName>
- <xref:System.IO.File.Open(System.String,System.IO.FileMode,System.IO.FileAccess)?displayProperty=fullName>
- <xref:System.IO.File.Open(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)?displayProperty=fullName>
- <xref:System.IO.File.OpenRead(System.String)?displayProperty=fullName>
- <xref:System.IO.File.OpenWrite(System.String)?displayProperty=fullName>
- <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>
- <xref:System.IO.FileInfo.Create?displayProperty=fullName>
- <xref:System.IO.FileInfo.Open%2A?displayProperty=fullName>
- <xref:System.IO.FileInfo.OpenRead?displayProperty=fullName>
- <xref:System.IO.FileInfo.OpenWrite?displayProperty=fullName>

## See also

- [FileStream no longer synchronizes file offset with OS (.NET 6)](../6.0/filestream-doesnt-sync-offset-with-os.md)
- [FileStream.Position updates after ReadAsync or WriteAsync completes (.NET 6)](../6.0/filestream-position-updates-after-readasync-writeasync-completion.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
title: ".NET 7 breaking change: Time fields on symbolic links"
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 .
ms.date: 10/04/2022
---
# Time fields on symbolic links

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:

- <xref:System.IO.FileSystemInfo.CreationTime>
- <xref:System.IO.FileSystemInfo.CreationTimeUtc>
- <xref:System.IO.FileSystemInfo.LastAccessTime>
- <xref:System.IO.FileSystemInfo.LastAccessTimeUtc>
- <xref:System.IO.FileSystemInfo.LastWriteTime>
- <xref:System.IO.FileSystemInfo.LastWriteTimeUtc>

## Previous behavior

Previously, updating any of the time-related fields on a symlink affected the fields of the symlink's target.

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.

```csharp
string filename = "file";
string linkname = "link";

// Create a file and symlink.
File.Create(filename).Dispose();
File.CreateSymbolicLink(linkname, filename);

Console.WriteLine("Before update:");
PrintMetadata(filename);
PrintMetadata(linkname);

UpdateMetadata(linkname);

Console.WriteLine("\nAfter update:");
PrintMetadata(filename);
PrintMetadata(linkname);

static void UpdateMetadata(string filename)
{
DateTime tomorrow = DateTime.Now.AddDays(1);

File.SetCreationTime(filename, tomorrow);
File.SetLastAccessTime(filename, tomorrow);
File.SetLastWriteTime(filename, tomorrow);
File.SetAttributes(filename, File.GetAttributes(filename) | FileAttributes.Offline);
}

static void PrintMetadata(string filename)
{
Console.WriteLine($"---{filename}---");
Console.WriteLine("Creation:\t" + File.GetCreationTime(filename));
Console.WriteLine("Last access:\t" + File.GetLastAccessTime(filename));
Console.WriteLine("Last write:\t" + File.GetLastWriteTime(filename));
Console.WriteLine("Attributes:\t" + File.GetAttributes(filename));
}
```

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:

```output
Before update:
---file---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive, ReparsePoint
After update:
---file---
Creation: 9/30/2022 10:35:40 AM
Last access: 9/30/2022 10:35:40 AM
Last write: 9/30/2022 10:35:40 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive, ReparsePoint, Offline
```

## New behavior

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.

The output of the program shown in the [Previous behavior](#previous-behavior) section is as follows:

```output
Before update:
---file---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive, ReparsePoint
After update:
---file---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive
---link---
Creation: 9/30/2022 10:33:39 AM
Last access: 9/30/2022 10:33:39 AM
Last write: 9/30/2022 10:33:39 AM
Attributes: Archive, ReparsePoint, Offline
```

## Version introduced

.NET 7 Preview 1

## Type of breaking change

This change can affect [source compatibility](../../categories.md#source-compatibility).

## Reason for change

The previous behavior was unexpected and undesirable in some cases:

- It was inconsistent with the behavior of the properties and methods that get the same fields.
- It was also impossible to actually update the fields in the symlink itself using .NET APIs.

## Recommended action

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.

```csharp
FileSystemInfo? targetInfo = linkInfo.ResolveLinkTarget(returnFinalTarget: true);
if (targetInfo != null)
{
// Update the properties accordingly.
targetInfo.LastWriteTime = DateTime.Now;
}
```

## Affected APIs

- <xref:System.IO.Directory.SetCreationTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.Directory.SetCreationTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.Directory.SetLastAccessTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.Directory.SetLastAccessTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.Directory.SetLastWriteTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.Directory.SetLastWriteTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetCreationTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetCreationTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetLastAccessTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetLastAccessTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetLastWriteTime(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.File.SetLastWriteTimeUtc(System.String,System.DateTime)?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.CreationTime?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.CreationTimeUtc?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.LastAccessTime?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.LastAccessTimeUtc?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.LastWriteTime?displayProperty=fullName>
- <xref:System.IO.FileSystemInfo.LastWriteTimeUtc?displayProperty=fullName>
8 changes: 8 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ items:
href: core-libraries/7.0/equals-nan.md
- name: Generic type constraint on PatternContext<T>
href: core-libraries/7.0/patterncontext-generic-constraint.md
- name: Legacy FileStream strategy removed
href: core-libraries/7.0/filestream-compat-switch.md
- name: Library support for older frameworks
href: core-libraries/7.0/old-framework-support.md
- name: Maximum precision for numeric format strings
Expand All @@ -77,6 +79,8 @@ items:
href: core-libraries/7.0/reflection-invoke-exceptions.md
- name: SerializationFormat.Binary is obsolete
href: core-libraries/7.0/serializationformat-binary.md
- name: Time fields on symbolic links
href: core-libraries/7.0/symbolic-link-timestamps.md
- name: Tracking linked cache entries
href: core-libraries/7.0/memorycache-tracking.md
- name: Validate CompressionLevel for BrotliStream
Expand Down Expand Up @@ -849,6 +853,8 @@ items:
href: core-libraries/7.0/equals-nan.md
- name: Generic type constraint on PatternContext<T>
href: core-libraries/7.0/patterncontext-generic-constraint.md
- name: Legacy FileStream strategy removed
href: core-libraries/7.0/filestream-compat-switch.md
- name: Library support for older frameworks
href: core-libraries/7.0/old-framework-support.md
- name: Maximum precision for numeric format strings
Expand All @@ -857,6 +863,8 @@ items:
href: core-libraries/7.0/reflection-invoke-exceptions.md
- name: SerializationFormat.Binary is obsolete
href: core-libraries/7.0/serializationformat-binary.md
- name: Time fields on symbolic links
href: core-libraries/7.0/symbolic-link-timestamps.md
- name: Tracking linked cache entries
href: core-libraries/7.0/memorycache-tracking.md
- name: Validate CompressionLevel for BrotliStream
Expand Down