public static void CreateSparse(string filename, long length) { if (!supportsSparse) { return; } // Ensure we have the full path filename = Path.GetFullPath(filename); try { if (!CanCreateSparse(filename)) { return; } // Create a file with the sparse flag enabled uint bytesReturned = 0; uint sharing = 0; // none uint attributes = 0x00000080; // Normal uint creation = 1; // Only create if new using ( SafeFileHandle handle = CreateFileW(filename, GENERIC_WRITE_ACCESS, sharing, IntPtr.Zero, creation, attributes, IntPtr.Zero)) { // If we couldn't create the file, bail out if (handle.IsInvalid) { return; } // If we can't set the sparse bit, bail out if ( !DeviceIoControl(handle, FSCTL_SET_SPARSE, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero)) { return; } // Tell the filesystem to mark bytes 0 -> length as sparse zeros var data = new FileZeroDataInformation(0, length); var structSize = (uint)Marshal.SizeOf(data); IntPtr ptr = Marshal.AllocHGlobal((int)structSize); try { Marshal.StructureToPtr(data, ptr, false); DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ptr, structSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero); } finally { Marshal.FreeHGlobal(ptr); } } } catch (DllNotFoundException) { supportsSparse = false; } catch (EntryPointNotFoundException) { supportsSparse = false; } catch { // Ignore for now. Maybe if i keep hitting this i should abort future attemts } }
public static void CreateSparse(string filename, long length) { if (!supportsSparse) return; // Ensure we have the full path filename = Path.GetFullPath(filename); try { if (!CanCreateSparse(filename)) return; // Create a file with the sparse flag enabled uint bytesReturned = 0; uint sharing = 0; // none uint attributes = 0x00000080; // Normal uint creation = 1; // Only create if new using ( SafeFileHandle handle = CreateFileW(filename, GENERIC_WRITE_ACCESS, sharing, IntPtr.Zero, creation, attributes, IntPtr.Zero)) { // If we couldn't create the file, bail out if (handle.IsInvalid) return; // If we can't set the sparse bit, bail out if ( !DeviceIoControl(handle, FSCTL_SET_SPARSE, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero)) return; // Tell the filesystem to mark bytes 0 -> length as sparse zeros var data = new FileZeroDataInformation(0, length); var structSize = (uint)Marshal.SizeOf(data); IntPtr ptr = Marshal.AllocHGlobal((int)structSize); try { Marshal.StructureToPtr(data, ptr, false); DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ptr, structSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero); } finally { Marshal.FreeHGlobal(ptr); } } } catch (DllNotFoundException) { supportsSparse = false; } catch (EntryPointNotFoundException) { supportsSparse = false; } catch { // Ignore for now. Maybe if i keep hitting this i should abort future attemts } }