C语言GetFileAttributesEx函数获取文件大小的疑惑
本帖最后由 mxwawaawxm 于 2022-8-10 20:39 编辑GetFileAttributesEx函数返回一个WIN32_FILE_ATTRIBUTE_DATA的结构体,
其中nFileSizeHigh是文件长度的高32位,nFileSizeLow是文件长度的低32位
所以文件的大小,按道理,应该是先让nFileSizeHigh先按位左移32位,再加上nFileSizeLow,就得到文件的大小。
但我在一本书中看到如下代码
定义变量ULONGLONG FileSize = nFileSizeHigh
然后FileSize <<= sizeof(WORD)*8;最后再加上nFileSizeLow,得到文件大小。
但奇怪的是,我打印了sizeof(WORD)*8的值,只移了16位,这是写错了吗。
我把FileSize <<= sizeof(WORD)*8;换成FileSize <<= 32;
两者数值是一样的
文件大小的数值依然对,是不是因为nFileSizeHigh都是0,所以移多少位,最后相加的数值都不变。
请大佬们帮忙看看。谢谢。
截图如下
代码如下
#include <windows.h>
#include <tchar.h>
void ByteToKMGT1(ULONGLONG FileSize);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT iCmdShow)
{
WIN32_FILE_ATTRIBUTE_DATA FileInfo;
PCTSTR pFileName = "d:\\ebooks\\辞典\\辞源第三版.pdf";
ULONGLONG FileSize;
if (GetFileAttributesEx(pFileName, GetFileExInfoStandard, &FileInfo)) {
_tprintf(TEXT("nFileSizeHigh:\t%lu 字节\n"), FileInfo.nFileSizeHigh);
_tprintf(TEXT("nFileSizeLow:\t%lu 字节\n"), FileInfo.nFileSizeLow);
FileSize = FileInfo.nFileSizeHigh;
// FileSize <<= 32;
FileSize <<= sizeof(WORD)*8;
_tprintf(TEXT("sizeof(WORD) * 8 = %I64u * 8 = %I64u\n"), sizeof(WORD), sizeof(WORD) * 8);
FileSize += FileInfo.nFileSizeLow;
_tprintf(TEXT("文件大小为:\t%I64u 字节\n"), FileSize);
ByteToKMGT1(FileSize);
}
return 0;
}
/* 把字节动态转换为KB、MB、GB、TB */
void ByteToKMGT1(ULONGLONG FileSize)
{
ULONGLONG Temp = FileSize;
// 统计换算1024的次数
int iCnt = 0;
while (Temp>=1024) {
Temp /= 1024;
iCnt++;
}
switch (iCnt) {
case 0:
_tprintf(TEXT("共计 %d B\n"), (int)FileSize);
break;
case 1:
_tprintf(TEXT("共计 %.4f KB\n"), FileSize/(float)1024);
break;
case 2:
_tprintf(TEXT("共计 %.4f MB\n"), FileSize/((float)1024*1024));
break;
case 3:
_tprintf(TEXT("共计 %.4f GB\n"), FileSize/((float)1024*1024*1024));
break;
case 4:
_tprintf(TEXT("共计 %.4f TB\n"), FileSize/((float)1024*1024*1024*1024));
break;
default :
break;
}
} 拿程序找个超过3G的文件试下 FileInfo.nFileSizeHigh 本身就是0 左移 还是0。只有非0时,左移右移才会发生值的变化。
最简单的是你把 FileSize= 1;然后再FileSize <<= 32; 值就变了 4294967296。 拿程序找个超过8G的文件试下 sizeof(WORD)*8=2*8
图片不是写的很清楚吗 不错,但是看不见 高苗苗 发表于 2022-8-9 14:25
拿程序找个超过3G的文件试下
我找了个3.8G的文件试了一下。
nFileSizeHigh还是0
即便不移位,也是能得到正确大小
clivia001 发表于 2022-8-9 16:54
sizeof(WORD)*8=2*8
图片不是写的很清楚吗
我是好奇FileSize <<= sizeof(WORD)*8
这样移16位,是不是写错了。
因为nFileSizeHigh是文件长度的高32位,nFileSizeLow是文件长度的低32位
这样照道理来说,不是要移32位吗。 mxwawaawxm 发表于 2022-8-9 21:37
我找了个3.8G的文件试了一下。
nFileSizeHigh还是0
即便不移位,也是能得到正确大小
我搞错了,昨天没注意,UINT32最长能表达4GB的长度,所以,应该是找个超过4G的文件试下 本帖最后由 mxwawaawxm 于 2022-8-10 22:24 编辑
高苗苗 发表于 2022-8-10 09:09
我搞错了,昨天没注意,UINT32最长能表达4GB的长度,所以,应该是找个超过4G的文件试下
谢谢。找了个6GB的文件测试。证明这样移位是错的
`FileSize <<= sizeof(WORD)*8;`
只移了16位,得这样写`FileSize <<= 32;`才能得到文件的正确大小。
页:
[1]