Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RandomAccess/File.OpenHandle in a few more places #55150

Merged
merged 1 commit into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 13 additions & 23 deletions src/libraries/System.Private.CoreLib/src/System/IO/File.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;

#if MS_IO_REDIST
using System;
Expand Down Expand Up @@ -373,19 +374,13 @@ public static void WriteAllBytes(string path, byte[] bytes)
if (bytes == null)
throw new ArgumentNullException(nameof(bytes));

InternalWriteAllBytes(path, bytes);
}

private static void InternalWriteAllBytes(string path, byte[] bytes)
{
Debug.Assert(path != null);
Debug.Assert(path.Length != 0);
Debug.Assert(bytes != null);

using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
fs.Write(bytes, 0, bytes.Length);
}
#if MS_IO_REDIST
using FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
fs.Write(bytes, 0, bytes.Length);
#else
using SafeFileHandle sfh = OpenHandle(path, FileMode.Create, FileAccess.Write, FileShare.Read);
RandomAccess.WriteAtOffset(sfh, bytes, 0);
#endif
}
public static string[] ReadAllLines(string path)
{
Expand Down Expand Up @@ -836,22 +831,17 @@ private static async Task<byte[]> InternalReadAllBytesUnknownLengthAsync(FileStr

return cancellationToken.IsCancellationRequested
? Task.FromCanceled(cancellationToken)
: InternalWriteAllBytesAsync(path, bytes, cancellationToken);
}

private static async Task InternalWriteAllBytesAsync(string path, byte[] bytes, CancellationToken cancellationToken)
{
Debug.Assert(!string.IsNullOrEmpty(path));
Debug.Assert(bytes != null);
: Core(path, bytes, cancellationToken);

using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, DefaultBufferSize, FileOptions.Asynchronous | FileOptions.SequentialScan))
static async Task Core(string path, byte[] bytes, CancellationToken cancellationToken)
{
#if MS_IO_REDIST
using FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, 1, FileOptions.Asynchronous | FileOptions.SequentialScan);
await fs.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false);
#else
await fs.WriteAsync(new ReadOnlyMemory<byte>(bytes), cancellationToken).ConfigureAwait(false);
using SafeFileHandle sfh = OpenHandle(path, FileMode.Create, FileAccess.Write, FileShare.Read, FileOptions.Asynchronous | FileOptions.SequentialScan);
await RandomAccess.WriteAtOffsetAsync(sfh, bytes, 0, cancellationToken).ConfigureAwait(false);
#endif
await fs.FlushAsync(cancellationToken).ConfigureAwait(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.Win32.SafeHandles;

namespace System.IO
{
Expand All @@ -25,10 +26,10 @@ public static void CopyFile(string sourceFullPath, string destFullPath, bool ove
}

// Copy the contents of the file from the source to the destination, creating the destination in the process
using (var src = new FileStream(sourceFullPath, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, FileOptions.None))
using (var dst = new FileStream(destFullPath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, DefaultBufferSize, FileOptions.None))
using (SafeFileHandle src = File.OpenHandle(sourceFullPath, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None))
using (SafeFileHandle dst = File.OpenHandle(destFullPath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, FileOptions.None))
{
Interop.CheckIo(Interop.Sys.CopyFile(src.SafeFileHandle, dst.SafeFileHandle));
Interop.CheckIo(Interop.Sys.CopyFile(src, dst));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ private static unsafe int WriteSyncUsingAsyncHandle(SafeFileHandle handle, ReadO
}
}

private static ValueTask<int> ReadAtOffsetAsync(SafeFileHandle handle, Memory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
internal static ValueTask<int> ReadAtOffsetAsync(SafeFileHandle handle, Memory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
=> handle.IsAsync
? Map(QueueAsyncReadFile(handle, buffer, fileOffset, cancellationToken))
: ScheduleSyncReadAtOffsetAsync(handle, buffer, fileOffset, cancellationToken);
Expand Down Expand Up @@ -269,7 +269,7 @@ internal static unsafe (SafeFileHandle.OverlappedValueTaskSource? vts, int error
return (vts, -1);
}

private static ValueTask<int> WriteAtOffsetAsync(SafeFileHandle handle, ReadOnlyMemory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
internal static ValueTask<int> WriteAtOffsetAsync(SafeFileHandle handle, ReadOnlyMemory<byte> buffer, long fileOffset, CancellationToken cancellationToken)
=> handle.IsAsync
? Map(QueueAsyncWriteFile(handle, buffer, fileOffset, cancellationToken))
: ScheduleSyncWriteAtOffsetAsync(handle, buffer, fileOffset, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Text;
using System.Threading;
using System.Security;
using Microsoft.Win32.SafeHandles;

namespace System
{
Expand Down Expand Up @@ -615,16 +616,17 @@ private static bool CompareTimeZoneFile(string filePath, byte[] buffer, byte[] r
try
{
// bufferSize == 1 used to avoid unnecessary buffer in FileStream
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1))
using (SafeFileHandle sfh = File.OpenHandle(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
if (stream.Length == rawData.Length)
long fileLength = RandomAccess.GetLength(sfh);
if (fileLength == rawData.Length)
{
int index = 0;
int count = rawData.Length;

while (count > 0)
{
int n = stream.Read(buffer, index, count);
int n = RandomAccess.Read(sfh, buffer.AsSpan(index, count), index);
if (n == 0)
ThrowHelper.ThrowEndOfFileException();

Expand Down