在windows中查找超过4gb的正确文件大小
Finding correct filesize over 4gb in windows
我已经用这个c++代码在windows中找到了一些文件的文件大小(使用visual studio(:
(p_findFileData->nFileSizeHigh * MAXDWORD) + p_findFileData->nFileSizeLow);
如果文件大于4gb,这不会给我正确的文件大小。经过一些研究,我尝试了:
(p_findFileData->nFileSizeHigh * (MAXDWORD+1)) + p_findFileData->nFileSizeLow);
当我读到nflesizehigh和nflesizelow分别是文件大小的64位值中的32位时,如果文件大小值大于32位,我们将maxdword(在我的情况下为0xffffff(乘以nflesizeheight。第二个解决方案也不起作用,给了我一个比原来更小的尺寸。我再次尝试了这个:
ULONGLONG FileSize = (FindFileData.nFileSizeHigh * 4294967296) + FindFileData.nFileSizeLow;
它奏效了。此外,我还使用了另一种解决方案来获得文件大小:
ULONGLONG FileSize = FindFileData.nFileSizeHigh;
FileSize <<= sizeof( FindFileData.nFileSizeHigh ) *8;
FileSize |= FindFileData.nFileSizeLow;
上述解决方案也适用:
我想知道为什么前两个解决方案不起作用,如果可能的话,还想知道最后一个解决方案的解释,因为我想知道代码的内部工作情况。我们将不胜感激。
使用ULARGE_INTEGER
结构来组合值,而不是尝试手动计算/移位它们:
ULARGE_INTEGER ul;
ul.HighPart = p_findFileData->nFileSizeHigh;
ul.LowPart = p_findFileData->nFileSizeLow;
ULONGLONG FileSize = ul.QuadPart;
我会使用:
ULONGLONG FileSize = (static_cast<ULONGLONG>(FindFileData.nFileSizeHigh) <<
sizeof(FindFileData.nFileSizeLow) *8) |
FindFileData.nFileSizeLow;
ULONGLONG的强制转换是必要的,以便在32位值进入FileSize变量之前将其转换为64位值。
当然,你也可以使用乘法,但它在任何特定方面都不会"更好",而且很可能会慢一点[在这种特殊情况下可能没有什么大不了的,但我认为使用乘法没有任何好处。
现在对于"不起作用"的变体:
即使这确实有效:
(p_findFileData->nFileSizeHigh * MAXDWORD) + p_findFileData->nFileSizeLow);
你会得到错误的值,因为MAXDWORD
比4GB小一个,所以你最终得到了错误的值[是的,它可能很接近,但它至少会错1个字节,可能更多]。然而,由于我们处理的是32位值,它实际上变成了:
-p_findFileData->nFileSizeHigh + p_findFileData->nFileSizeLow;
因为MAXDWORD
与-1相同(是的,它很可能是一个无符号值,但如果以这种方式使值溢出,它的行为与负符号值相同(。
这个在数学上是正确的,但由于它溢出了一个32位的值,所以不起作用。
(p_findFileData->nFileSizeHigh * (MAXDWORD+1)) + p_findFileData->nFileSizeLow);
所以你得到了low part + (0 * high part)
,这当然是不正确的。
有了演员阵容,这将起作用:
static_cast<ULONGLONG>(p_findFileData->nFileSizeHigh) * (MAXDWORD+1) +
p_findFileData->nFileSizeLow;
(p_findFileData->nFileSizeHigh * MAXDWORD) + p_findFileData->nFileSizeLow);
这不会给出正确的结果,因为MAXDWORD是错误的值。
(p_findFileData->nFileSizeHigh * (MAXDWORD+1)) + p_findFileData->nFileSizeLow);
这不起作用,因为在将类型强制转换为足够大的值之前,要将+1添加到MAXDWORD中。
(FindFileData.nFileSizeHigh * 4294967296) + FindFileData.nFileSizeLow;
这是因为4294967296
是64位类型。
FileSize <<= sizeof( FindFileData.nFileSizeHigh ) *8;
FileSize |= FindFileData.nFileSizeLow;
这是因为您将高位移位32(这与乘以4294967296相同(,然后使用按位或"相加"低位。
我遇到了完全相同的问题,答案对我的代码来说非常简单。只需将MAXDWORD强制转换为64位int(例如uint64_t(。这背后的解释可以从我在这里收到的答案中找到。
- 读取某些文件时出现分段错误,似乎与文件大小无关
- 构建挂起,即使是适度的文件大小
- 如何在Windows内核中获取文件大小
- 为什么 QFileSystemWatcher 会发出多个信号?而 QFileInfo 首次写入零文件大小
- 使用 C++ iOS::ate 获取错误的文件大小
- 相同的源代码,不同的可执行文件大小?
- 为什么未关闭的文件大小为 4 字节
- 读取二进制文件大小的短自上周以来停止工作
- 如何减小C++标准库libstdc++.so文件大小
- 文件大小和缓冲区过冲
- 如何从范围 v3 的istream_range中检索文件大小?
- 如何使用直接IO编写一个带有扩展文件大小的小文件
- 如何使用文件系统库获取"true"文件大小?(C++17)
- 如何限制文件大小,以便我的程序在变大之后创建一个新文件?并编辑新创建的文件的名称
- 如何使用C 17获取文件大小
- HttpQueryInfo 获取文件大小
- 二进制文件大小大于预期的 c++
- 如何计算预期的核心文件大小
- C :不正确的文件大小计算Winapi
- 在windows中查找超过4gb的正确文件大小