我试图分析一个基本的读取操作使用ifstream与Procmon。
用于读取操作的部分代码,其中我试图从文件中读取16kb大小的数据:
char * buffer = new char[128000];
ifstream fileHandle("file.txt");
fileHandle.read(buffer, 16000);
cout << buffer << endl;
fileHandle.close();
在Procmon中有4个ReadFile操作,具体如下:
Offset: 0, Length: 4,096, Priority: Normal
偏移量:4096,长度:4096
偏移量:8192,长度:4096
偏移量:12288,长度:4096
那么这是否意味着有4个操作,每个操作大小为4kb ?如果是这样的话,为什么会发生这种情况,而不是只进行一个16 kb大小的ReadFile操作呢?
那么这是否意味着有4个操作,每个操作大小为4kb ?
是的。
,如果是这样的话,为什么会发生这样的情况,而不是只有一个16 kb大小的ReadFile操作。
可能是因为编译器附带的标准库将文件流缓冲区的默认大小设置为4kb;由于read
操作必须通过缓冲区,因此在满足您的请求之前必须填充(通过操作系统调用)并清空4次。注意,您可以使用fileHandle.rdbuf->pubsetbuf
更改fstream
的内部缓冲区。
那么这是否意味着有4个操作,每个操作大小为4kb ?
它就是这么说的。
,如果是这样的话,为什么会发生这样的情况,而不是只有一个16 kb大小的ReadFile操作。
仅仅因为您请求16000字节并不意味着ifstream
实际上可以在单个操作中读取16000字节。文件系统通常不允许这么大的读取,通常有一个上限。即使你增加了ifstream
内部使用的内部缓冲区的大小,这仍然不能保证文件系统会支持更大的读取大小。
read()
的约定是,除非遇到EOF/错误,否则它会返回请求的字节数。它如何在内部完成读取是一个实现细节。在这种情况下,ifstream
必须读取四个4KB块才能返回16000字节。