如何使用Win32 API创建指定大小文件并填充固定数值
解决方案
你已经完成了指定大小文件的创建,要实现全文件填充指定数值,有两种常用的高效实现方式:
方案1:分块循环写入(适合小文件,逻辑简单)
你调用SetEndOfFile后文件指针停在文件末尾,首先需要把指针移回文件起始位置,再循环写入预填充好指定值的缓冲区即可,参考代码如下:
// 第一步:把文件指针移回文件开头 LARGE_INTEGER zeroOffset = {0}; if (!SetFilePointerEx(hFile, zeroOffset, nullptr, FILE_BEGIN)) { CloseHandle(hFile); return false; } // 第二步:创建填充缓冲区,这里用64KB块,可根据需求调整大小 const DWORD bufferSize = 64 * 1024; BYTE* buffer = new BYTE[bufferSize]; // 填充为你要的数值,比如填'1'就是0x31,填0就是0x00 memset(buffer, 0x31, bufferSize); // 第三步:循环写入直到写满整个文件 ULONGLONG remainSize = uFileSize; DWORD writtenBytes = 0; while (remainSize > 0) { DWORD toWrite = (remainSize > bufferSize) ? bufferSize : (DWORD)remainSize; if (!WriteFile(hFile, buffer, toWrite, &writtenBytes, nullptr)) { delete[] buffer; CloseHandle(hFile); return false; } remainSize -= writtenBytes; } delete[] buffer; // 后续操作:关闭文件句柄等
注意:你当前创建文件时带了FILE_FLAG_OVERLAPPED异步IO标志,如果需要保留异步逻辑,需要给每个WriteFile调用传入初始化了偏移量的OVERLAPPED结构,并处理IO完成通知。
方案2:内存映射文件(适合大文件,性能更高)
如果需要填充的文件体积较大(GB级别),用内存映射的方式效率远高于循环写入,不需要频繁调用IO接口,直接操作内存即可:
// 前面创建文件、设置文件大小的逻辑不变 // 第一步:创建文件映射对象 HANDLE hMap = CreateFileMappingA(hFile, nullptr, PAGE_READWRITE, 0, 0, nullptr); if (hMap == nullptr) { CloseHandle(hFile); return false; } // 第二步:映射整个文件到进程地址空间 LPVOID mapAddr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (mapAddr == nullptr) { CloseHandle(hMap); CloseHandle(hFile); return false; } // 第三步:直接填充内存,就是填充整个文件,这里填'1' memset(mapAddr, 0x31, uFileSize); // 第四步:释放资源 UnmapViewOfFile(mapAddr); CloseHandle(hMap); // 后续关闭hFile即可
内容的提问来源于stack exchange,提问作者James Franco
相关产品推荐
相关产品推荐

