How to do non-cached file writes in C# winform app

后端 未结 1 957
感动是毒
感动是毒 2020-12-24 15:31

I\'m trying to determine worst case disk speed, so I wrote the following function.

static public decimal MBytesPerSec(string volume)
{
    string filename =         


        
相关标签:
1条回答
  • 2020-12-24 16:19

    Try some unmanaged code:

    [DllImport("kernel32", SetLastError = true)]
            static extern unsafe SafeFileHandle CreateFile(
                string FileName,           // file name
                uint DesiredAccess,        // access mode
                uint ShareMode,            // share mode
                IntPtr SecurityAttributes, // Security Attr
                uint CreationDisposition,  // how to create
                uint FlagsAndAttributes,   // file attributes
                IntPtr hTemplate // template file  
                );
    const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
    
    SafeFileHandle handle = CreateFile("filename",
                                (uint)FileAccess.Write,
                                (uint)FileShare.None,
                                IntPtr.Zero,
                                (uint)FileMode.Open,
                                 FILE_FLAG_NO_BUFFERING,
                                IntPtr.Zero);
    
    var unBufferedStream = new FileStream(handle,FileAccess.Read,blockSize,false);
    

    now you should have access to an unbuffered stream which you can read and write however you please with no constraints

    For the record....you can also disable caching like this:

    [DllImport("KERNEL32", SetLastError = true)]
            public extern static int DeviceIoControl(IntPtr hDevice, uint IoControlCode,
                IntPtr lpInBuffer, uint InBufferSize,
                IntPtr lpOutBuffer, uint nOutBufferSize,
                ref uint lpBytesReturned,
                IntPtr lpOverlapped);
            [DllImport("KERNEL32", SetLastError = true)]
            public extern static int CloseHandle(
            IntPtr hObject);
    
    [StructLayout(LayoutKind.Sequential)]
            public struct DISK_CACHE_INFORMATION
            {            
                public byte ParametersSavable;            
                public byte ReadCacheEnabled;            
                public byte WriteCacheEnabled;
                public int ReadRetentionPriority;//DISK_CACHE_RETENTION_PRIORITY = enum = int
                public int WriteRetentionPriority;//DISK_CACHE_RETENTION_PRIORITY = enum = int
                public Int16 DisablePrefetchTransferLength;//WORD            
                public byte PrefetchScalar;            
            }
    
    public void SetDiskCache(byte val)
            {
                IntPtr h = CreateFile("\\\\.\\PHYSICALDRIVE0", (uint)FileAccess.Read | (uint)FileAccess.Write, (uint)FileShare.Write, IntPtr.Zero, (uint)FileMode.Open, 0, IntPtr.Zero);
                DISK_CACHE_INFORMATION sInfo = new DISK_CACHE_INFORMATION();
                IntPtr ptrout = Marshal.AllocHGlobal(Marshal.SizeOf(sInfo));
                Marshal.StructureToPtr(sInfo, ptrout, true);            
                uint dwWritten = 0;
                int ret = DeviceIoControl(h,IOCTL_DISK_GET_CACHE_INFORMATION,IntPtr.Zero,0,ptrout,(uint)Marshal.SizeOf(sInfo),ref dwWritten,IntPtr.Zero);            
                sInfo = (DISK_CACHE_INFORMATION)Marshal.PtrToStructure(ptrout,typeof(DISK_CACHE_INFORMATION));            
                sInfo.ReadCacheEnabled = val;
                // acuma trimite structura modificata
                IntPtr ptrin = Marshal.AllocHGlobal(Marshal.SizeOf(sInfo));
                Marshal.StructureToPtr(sInfo, ptrin, true);            
                ret = DeviceIoControl(h, IOCTL_DISK_SET_CACHE_INFORMATION, ptrin, (uint)Marshal.SizeOf(sInfo), IntPtr.Zero, 0, ref dwWritten, IntPtr.Zero);            
                CloseHandle(h);            
            }
    
    0 讨论(0)
提交回复
热议问题