在.NET中执行文件IO时,似乎95%的示例使用4096字节缓冲区。 4kb缓冲长度有什么特别之处?或者它只是在for循环中使用i作为索引的惯例?
答案 0 :(得分:8)
这是因为4K是高达16TB的磁盘的默认簇大小。因此,在选择缓冲区大小时,将缓冲区分配为簇大小的倍数是有意义的。
群集是文件的最小分配单位,因此如果文件只包含1个字节,则会占用4K的物理磁盘空间。并且5K的文件将导致8K分配。
<小时/> 更新:添加了一个代码示例,用于获取驱动器的群集大小
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("kernel32", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetDiskFreeSpace(
string rootPathName,
out int sectorsPerCluster,
out int bytesPerSector,
out int numberOfFreeClusters,
out int totalNumberOfClusters);
static void Main(string[] args)
{
int sectorsPerCluster;
int bytesPerSector;
int numberOfFreeClusters;
int totalNumberOfClusters;
if (GetDiskFreeSpace("C:\\",
out sectorsPerCluster,
out bytesPerSector,
out numberOfFreeClusters,
out totalNumberOfClusters))
{
Console.WriteLine("Cluster size = {0} bytes",
sectorsPerCluster * bytesPerSector);
}
else
{
Console.WriteLine("GetDiskFreeSpace Failed: {0:x}",
Marshal.GetLastWin32Error());
}
Console.ReadKey();
}
}
答案 1 :(得分:1)
一些因素:
最重要的是,多年来由于上述原因,很多人使用4K作为缓冲区长度,因此大量的IO和OS代码针对4K缓冲区进行了优化!
答案 2 :(得分:0)
我的猜测是它与操作系统文件块大小相关 - 在.NET上的Windows。
答案 3 :(得分:0)
我的猜测……我的答案是正确的,而其他答案则是不正确的-在历史上不够深入。 而且知道这是一个古老的问题,更重要的是要提到的是,在什么时候性能不是仅是编程风格的问题。
二进制大小(4096、8192或有时为1024)来自于您看到CPU与外围芯片的连接的时间。 听起来很老,很抱歉,但这对于回答您的问题至关重要。 程序中的缓冲区必须移至外围设备,因此它需要地址线(今天需要其他想法),并且该地址线是二进制有界的。 并且芯片获取需要(和需要)内存的信息以保留它。该内存是由二进制地址确定的(!)...-您找不到23gb的芯片。 1k,2k,4k或(最终)8k是一个好值(在过去)。
如何移出一个字节同时需要移出8k的缓冲区(有些情况下是这样)。这就是为什么我们有缓冲区!
硬盘具有此(群集)大小不是缓冲区大小的原因-相反,这是正确的-硬盘的组织遵循上述系统。