大家,我每秒有很多文件写入磁盘,我想禁用磁盘缓存以提高性能,我谷歌搜索找到解决方案:win32 CreateFile method with FILE_FLAG_NO_BUFFERING 和How to empty/flush Windows READ disk cache in C#? .
我写了一点代码来测试是否可以工作:
const int FILE_FLAG_NO_BUFFERING = unchecked((int)0x20000000);
[DllImport("KERNEL32", SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
static extern SafeFileHandle CreateFile(
String fileName,
int desiredAccess,
System.IO.FileShare shareMode,
IntPtr securityAttrs,
System.IO.FileMode creationDisposition,
int flagsAndAttributes,
IntPtr templateFile);
static void Main(string[] args)
{
var handler = CreateFile(@"d:\temp.bin", (int)FileAccess.Write, FileShare.None,IntPtr.Zero, FileMode.Create, FILE_FLAG_NO_BUFFERING, IntPtr.Zero);
var stream = new FileStream(handler, FileAccess.Write, BlockSize);//BlockSize=4096
byte[] array = Encoding.UTF8.GetBytes("hello,world");
stream.Write(array, 0, array.Length);
stream.Close();
}
运行此程序时,应用程序出现异常:IO operation will not work。很可能文件会变得太长或句柄未打开以支持同步 IO 操作
后来,我发现这篇文章当你创建一个带有约束的对象时,你必须确保使用该对象的每个人都理解这些约束,但我不能完全理解,所以我改变我的代码来测试:
var stream = new FileStream(handler, FileAccess.Write, 4096);
byte[] ioBuffer = new byte[4096];
byte[] array = Encoding.UTF8.GetBytes("hello,world");
Array.Copy(array, ioBuffer, array.Length);
stream.Write(ioBuffer, 0, ioBuffer.Length);
stream.Close();
它运行正常,但我只想要“hello,world”字节而不是全部。我尝试将块大小更改为 1 或其他整数(不是 512 倍数)得到相同的错误。我也尝试 win32 WriteFile api 也得到相同的错误。有人可以帮助我?