.netpowershellntfshard-drivesystem.io.file

Powershell / .NET - Will [System.IO.File] give me the same result as file copy in NTFS?


I am just trying to write a basic powershell script to test certain performance characteristics of hard drives. It's basically generating files of random content of $fsizefill bytes and writing it to the hard drive.

I managed to piece together this lovely piece of code (thanks stackoverflow):

    [System.Security.Cryptography.RNGCryptoServiceProvider] $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
    $rndbytes = New-Object byte[] $fsizefill
    $rng.GetBytes($rndbytes)
    $StopWatch=[system.diagnostics.stopwatch]::startnew()
    [System.IO.File]::WriteAllBytes("$dpath`\$fname", $rndbytes)
    $SecondsElapsed=$StopWatch.Elapsed.TotalSeconds

If I am looking at file copy performance though, will this provide the same result? Because this seems like it will stream the data rather than perform a file copy.


Solution

  • because it ends up in a different c++ call.
    If you look to the source on https://source.dot.net/

    WriteAllBytes will end up in a system native SystemNative_Write
    and File.Copy will end up in SystemNative_CopyFile.

    https://source.dot.net/#System.Private.CoreLib/Interop.Write.cs,097fad085ae36eb7
    https://source.dot.net/#System.Private.CoreLib/Interop.CopyFile.cs,8a8c7aa8301ca2e8

    But too answer your question, WriteAllBytes results in a Filestream, you will get the biggest performance changes adjusting Buffersize and FileOptions parameters in the Filestream class.

    On windows i expect a win api call for createfile
    https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
    to copy a stream.

    For file copy i would expect copyfileex
    https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfileexw
    as system native implementation.