Skip to content

Configure FileStreamOptions with PreallocationSize and async access in ZipArchiveEntry extract methods#125260

Open
rzikm wants to merge 2 commits intodotnet:mainfrom
rzikm:ziparchiveentry-extracttofile-options-98cb
Open

Configure FileStreamOptions with PreallocationSize and async access in ZipArchiveEntry extract methods#125260
rzikm wants to merge 2 commits intodotnet:mainfrom
rzikm:ziparchiveentry-extracttofile-options-98cb

Conversation

@rzikm
Copy link
Member

@rzikm rzikm commented Mar 6, 2026

Set PreallocationSize on FileStreamOptions based on the entry's uncompressed size (ZipArchiveEntry.Length) to allow the file system to pre-allocate disk space, reducing fragmentation and improving write performance.

Configure FileOptions.Asynchronous when extracting from async methods (ExtractToFileAsync) so the FileStream uses async I/O.

Copilot AI review requested due to automatic review settings March 6, 2026 08:44
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @karelz, @dotnet/area-system-io-compression
See info in area-owners.md if you want to be subscribed.

@rzikm rzikm requested a review from a team March 6, 2026 08:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves ZipArchiveEntry extraction performance/behavior by configuring FileStreamOptions to (1) preallocate disk space based on the entry’s uncompressed size and (2) enable async file I/O when extracting via async APIs.

Changes:

  • Set FileStreamOptions.PreallocationSize from ZipArchiveEntry.Length during extraction initialization.
  • Thread an async flag into the shared initialization helper to set FileOptions.Asynchronous for ExtractToFileAsync.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs Adds preallocation and async/sync option selection to the shared file-creation options.
src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs Passes the async flag so extracted file streams use async I/O.

You can also share your feedback on Copilot code review. Take the survey.

…n ZipArchiveEntry extract methods

Set PreallocationSize based on the entry's uncompressed size to allow the
file system to pre-allocate disk space, reducing fragmentation and improving
write performance.

Configure FileOptions.Asynchronous when extracting from async methods so
that the FileStream uses async I/O.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rzikm rzikm force-pushed the ziparchiveentry-extracttofile-options-98cb branch from 1d2f2aa to 3c51c56 Compare March 6, 2026 09:14
ZipArchiveEntry.Length throws InvalidOperationException when the entry
has been opened for writing (e.g. in Update mode). Read it in a
try/catch and fall back to 0 (no preallocation) to avoid regressing
that scenario.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 6, 2026 10:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


You can also share your feedback on Copilot code review. Take the survey.

{
preallocationSize = source.Length;
}
catch (InvalidOperationException) { }
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty catch (InvalidOperationException) { } makes it unclear why ZipArchiveEntry.Length is expected to fail here and why it’s safe to ignore. Please add a short comment explaining the specific scenario(s) (e.g., entry not readable / length not available) and that preallocation is best-effort, so future changes don’t accidentally rely on preallocationSize being accurate.

Suggested change
catch (InvalidOperationException) { }
catch (InvalidOperationException)
{
// Length can throw if the entry is not readable or its size is not yet available (for example,
// when the archive is in a mode that does not expose the entry length). In that case we skip
// preallocation and leave preallocationSize as 0. This is a best-effort optimization only and
// callers must not rely on PreallocationSize matching the final file size.
}

Copilot uses AI. Check for mistakes.
long preallocationSize = 0;
try
{
preallocationSize = source.Length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the try/catch because the stream may not be seekable? It should instead check CanSeek

Mode = overwrite ? FileMode.Create : FileMode.CreateNew,
Share = FileShare.None,
BufferSize = ZipFile.FileStreamBufferSize,
PreallocationSize = preallocationSize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you measure any impact from this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants