private async Task CopyFileWithStreamsAsync(AbsolutePath sourcePath, AbsolutePath destinationPath, bool replaceExisting)
        {
            // It is very important to call OpenInternal and not to call OpenAsync method that will re-acquire the semaphore once again.
            // Violating this rule may cause a deadlock.
            using (Stream? readStream = TryOpenFile(
                       sourcePath, FileAccess.Read, FileMode.Open, FileShare.Read | FileShare.Delete, FileOptions.None, AbsFileSystemExtension.DefaultFileStreamBufferSize))
            {
                if (readStream == null)
                {
                    var message = string.Format(CultureInfo.InvariantCulture, "missing source file=[{0}]", sourcePath);
                    throw new FileNotFoundException(message, sourcePath.Path);
                }

                CreateDirectory(destinationPath.GetParent());

                // If asked to replace the file Create mode must be use to truncate the content of the file
                // if the target file larger than the source.
                var mode = replaceExisting ? FileMode.Create : FileMode.CreateNew;

                using (Stream? writeStream = TryOpenFile(
                           destinationPath, FileAccess.Write, mode, FileShare.Delete, FileOptions.None, AbsFileSystemExtension.DefaultFileStreamBufferSize))
                {
                    if (writeStream == null)
                    {
                        var message = string.Format(CultureInfo.InvariantCulture, "missing destination file=[{0}]", sourcePath);
                        throw new FileNotFoundException(message, sourcePath.Path);
                    }

                    await readStream.CopyToWithFullBufferAsync(writeStream, FileSystemConstants.FileIOBufferSize).ConfigureAwait(false);
                }
            }
        }
        /// <summary>
        ///     Copy a file from one path to another synchronously.
        /// </summary>
        public void CopyFile(AbsolutePath sourcePath, AbsolutePath destinationPath, bool replaceExisting)
        {
            sourcePath.ThrowIfPathTooLong();
            destinationPath.ThrowIfPathTooLong();

            if (!FileUtilities.FileExistsNoFollow(sourcePath.Path))
            {
                var message = string.Format(CultureInfo.InvariantCulture, "missing source file=[{0}]", sourcePath);
                throw new FileNotFoundException(message, sourcePath.Path);
            }

            if (FileUtilities.IsCopyOnWriteSupportedByEnlistmentVolume)
            {
                var possiblyDeleteExistingDestination = FileUtilities.TryDeletePathIfExists(destinationPath.Path);
                if (!possiblyDeleteExistingDestination.Succeeded)
                {
                    throw possiblyDeleteExistingDestination.Failure.CreateException();
                }

                CreateDirectory(destinationPath.GetParent());

                var possiblyCreateCopyOnWrite = FileUtilities.TryCreateCopyOnWrite(sourcePath.Path, destinationPath.Path, followSymlink: false);

                if (possiblyCreateCopyOnWrite.Succeeded)
                {
                    return;
                }
            }

            File.Copy(sourcePath.Path, destinationPath.Path, replaceExisting);
        }
        private Task <bool> TryInKernelFileCopyAsync(
            AbsolutePath sourcePath,
            AbsolutePath destinationPath,
            bool replaceExisting)
        {
            return(Task.Run(() =>
            {
                if (!FileUtilities.FileExistsNoFollow(sourcePath.Path))
                {
                    return false;
                }

                if (replaceExisting)
                {
                    var possiblyDeleteExistingDestination = FileUtilities.TryDeletePathIfExists(destinationPath.Path);

                    if (!possiblyDeleteExistingDestination.Succeeded)
                    {
                        return false;
                    }
                }

                CreateDirectory(destinationPath.GetParent());

                var possibleInKernelFileCopy = FileUtilities.TryInKernelFileCopy(sourcePath.Path, destinationPath.Path, followSymlink: false);

                return possibleInKernelFileCopy.Succeeded;
            }));
        }
        private async Task CopyFileWithStreamsAsync(AbsolutePath sourcePath, AbsolutePath destinationPath, bool replaceExisting)
        {
            using (StreamWithLength? readStream = TryOpenFile(
                       sourcePath, FileAccess.Read, FileMode.Open, FileShare.Read | FileShare.Delete, FileOptions.None, AbsFileSystemExtension.DefaultFileStreamBufferSize))
            {
                if (readStream == null)
                {
                    var message = string.Format(CultureInfo.InvariantCulture, "missing source file=[{0}]", sourcePath);
                    throw new FileNotFoundException(message, sourcePath.Path);
                }

                CreateDirectory(destinationPath.GetParent());

                // If asked to replace the file Create mode must be use to truncate the content of the file
                // if the target file larger than the source.
                var mode = replaceExisting ? FileMode.Create : FileMode.CreateNew;
                using (Stream? writeStream = this.OpenForWrite(destinationPath, readStream.Value.Length, mode, FileShare.Delete))
                {
                    if (writeStream == null)
                    {
                        var message = string.Format(CultureInfo.InvariantCulture, "missing destination file=[{0}]", sourcePath);
                        throw new FileNotFoundException(message, sourcePath.Path);
                    }

                    using var pooledHandle = GlobalObjectPools.FileIOBuffersArrayPool.Get();
                    await readStream.Value.Stream.CopyToWithFullBufferAsync(writeStream, pooledHandle.Value).ConfigureAwait(false);
                }
            }
        }