Dưới đây là một số mã để sử dụng tập tin thưa thớt:
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Microsoft.Win32.SafeHandles;
public static class SparseFiles
{
private const int FILE_SUPPORTS_SPARSE_FILES = 64;
private const int FSCTL_SET_SPARSE = 0x000900c4;
private const int FSCTL_SET_ZERO_DATA = 0x000980c8;
public static void MakeSparse(this FileStream fileStream)
{
var bytesReturned = 0;
var lpOverlapped = new NativeOverlapped();
var result = DeviceIoControl(
fileStream.SafeFileHandle,
FSCTL_SET_SPARSE,
IntPtr.Zero,
0,
IntPtr.Zero,
0,
ref bytesReturned,
ref lpOverlapped);
if (!result)
{
throw new Win32Exception();
}
}
public static void SetSparseRange(this FileStream fileStream, long fileOffset, long length)
{
var fzd = new FILE_ZERO_DATA_INFORMATION();
fzd.FileOffset = fileOffset;
fzd.BeyondFinalZero = fileOffset + length;
var lpOverlapped = new NativeOverlapped();
var dwTemp = 0;
var result = DeviceIoControl(
fileStream.SafeFileHandle,
FSCTL_SET_ZERO_DATA,
ref fzd,
Marshal.SizeOf(typeof(FILE_ZERO_DATA_INFORMATION)),
IntPtr.Zero,
0,
ref dwTemp,
ref lpOverlapped);
if (!result)
{
throw new Win32Exception();
}
}
public static bool SupportedOnVolume(string filename)
{
var targetVolume = Path.GetPathRoot(filename);
var fileSystemName = new StringBuilder(300);
var volumeName = new StringBuilder(300);
uint lpFileSystemFlags;
uint lpVolumeSerialNumber;
uint lpMaxComponentLength;
var result = GetVolumeInformationW(
targetVolume,
volumeName,
(uint)volumeName.Capacity,
out lpVolumeSerialNumber,
out lpMaxComponentLength,
out lpFileSystemFlags,
fileSystemName,
(uint)fileSystemName.Capacity);
if (!result)
{
throw new Win32Exception();
}
return (lpFileSystemFlags & FILE_SUPPORTS_SPARSE_FILES) == FILE_SUPPORTS_SPARSE_FILES;
}
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeviceIoControl(
SafeFileHandle hDevice,
int dwIoControlCode,
IntPtr InBuffer,
int nInBufferSize,
IntPtr OutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
[In] ref NativeOverlapped lpOverlapped);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeviceIoControl(
SafeFileHandle hDevice,
int dwIoControlCode,
ref FILE_ZERO_DATA_INFORMATION InBuffer,
int nInBufferSize,
IntPtr OutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
[In] ref NativeOverlapped lpOverlapped);
[DllImport("kernel32.dll", EntryPoint = "GetVolumeInformationW")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetVolumeInformationW(
[In] [MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName,
[Out] [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpVolumeNameBuffer,
uint nVolumeNameSize,
out uint lpVolumeSerialNumber,
out uint lpMaximumComponentLength,
out uint lpFileSystemFlags,
[Out] [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpFileSystemNameBuffer,
uint nFileSystemNameSize);
[StructLayout(LayoutKind.Sequential)]
private struct FILE_ZERO_DATA_INFORMATION
{
public long FileOffset;
public long BeyondFinalZero;
}
}
Và mẫu mã để kiểm tra các lớp trên.
class Program
{
static void Main(string[] args)
{
using (var fileStream = new FileStream("test", FileMode.Create, FileAccess.ReadWrite, FileShare.None))
{
fileStream.SetLength(1024 * 1024 * 128);
fileStream.MakeSparse();
fileStream.SetSparseRange(0, fileStream.Length);
}
}
}
Hope this helps
Cảm ơn bạn đã phản ứng, điều này rất thú vị. Tôi đã có ấn tượng rằng FileStream.SetLength() đã tạo ra một tệp thưa thớt. Tôi có sai về điều đó không? Tôi đang cố gắng tránh tác động đến hiệu suất phát sinh khi ghi vào một tệp thưa thớt tại một điểm tìm kiếm lớn. Tôi không hoàn toàn rõ ràng về cách này sẽ tránh được vấn đề đó. – revoxover
Nội bộ SetLength đang gọi [SetEndOfFile] (http://msdn.microsoft.com/en-us/library/aa365531%28v=vs.85%29.aspx). Tôi không biết nếu đó là tạo ra một tập tin thưa thớt hay không. –
Chỉ cần chạy một thử nghiệm nhanh chóng, nó không. –