在Windows MSVC6中,类似fseek、ftell等的普通文件相关函数只能处理最大2GB的文件(据我目前的了解,如有错误请指正)。
我想处理大于2GB的文件。应该怎么做?有哪些可用的函数?
ftell
,fseek
函数使用32位整数,因此您将无法处理大于4GB的文件。您必须直接使用操作系统 API。GetFileSizeEx
,因此您必须确保使用使用64位文件偏移量的函数。同样适用于SetFilePointerEx
。这个限制可能源于文件系统。FAT32的限制是4GB,而NTFS有更高的限制(以TB为单位)。
因此,您可以处理的文件大小取决于硬盘已经格式化为哪种文件系统以及您正在使用哪个操作系统,尽管您几乎肯定在使用能够处理NTFS上限的操作系统(Windows 2000或更高版本)。
大部分情况下,您需要忽略标准库中内置的所有文件函数,而只使用Win32 API中的函数——例如,您需要使用WriteFile
而不是fwrite
或ostream::write
,需要使用SetFilePointer
而不是fseek
或seekp
来在文件中寻找。大多数Win32 API都可以处理大于4 GB的文件,而那些不能处理的API也有可以处理较大文件的替代品。
您可以使用Windows API来处理文件,例如CreateFile、ReadFile和WriteFile。这也为您提供了重叠和非重叠操作的选项。
实际上是16TB(对于将来发现此问题的任何人)。我刚刚使用重叠I/O创建了一个6GB的文件,以下代码片段展示了如何处理偏移量: OVERLAPPED ol; __int64 fileOffset; ol.hEvent = CreateEvent(0, TRUE, FALSE, 0); fileOffset = __int64(TEST_BUFFER_SIZE) * i; ol.Offset = (DWORD)fileOffset; ol.OffsetHigh = (DWORD)(fileOffset >> 32); printf("[%d %I64d] ", i, fileOffset); result = WriteFile(hFile, buffer, TEST_BUFFER_SIZE, &written, &ol);
要获取大小,可以执行以下操作...
DWORD dwHigh, dwLow =GetFileSize(hFile, &dwHigh);
__int64 FileSizeInBytes = __int64(dwHigh * (MAXDWORD + 1.0L)) + dwLow;