吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1255|回复: 9
收起左侧

[已解决] C语言GetFileAttributesEx函数获取文件大小的疑惑

  [复制链接]
mxwawaawxm 发表于 2022-8-9 13:15
本帖最后由 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,所以移多少位,最后相加的数值都不变。
请大佬们帮忙看看。谢谢。

截图如下 2022-08-09_131123.png 2022-08-09_131233.png
代码如下
[C] 纯文本查看 复制代码
#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;            
    }
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

高苗苗 发表于 2022-8-9 14:25
拿程序找个超过3G的文件试下
Eaglecad 发表于 2022-8-9 15:39
FileInfo.nFileSizeHigh 本身就是0 左移 还是0。只有非0时,左移右移才会发生值的变化。
最简单的是你把 FileSize= 1;  然后再  FileSize <<= 32; 值就变了 4294967296。
iawyxkdn8 发表于 2022-8-9 16:16
clivia001 发表于 2022-8-9 16:54
sizeof(WORD)*8=2*8
图片不是写的很清楚吗
葡萄 发表于 2022-8-9 19:07
不错,但是看不见
 楼主| mxwawaawxm 发表于 2022-8-9 21:37
高苗苗 发表于 2022-8-9 14:25
拿程序找个超过3G的文件试下

我找了个3.8G的文件试了一下。
nFileSizeHigh还是0
即便不移位,也是能得到正确大小
2022-08-09_213700.png
 楼主| mxwawaawxm 发表于 2022-8-9 21:39
clivia001 发表于 2022-8-9 16:54
sizeof(WORD)*8=2*8
图片不是写的很清楚吗

我是好奇FileSize <<= sizeof(WORD)*8
这样移16位,是不是写错了。
因为nFileSizeHigh是文件长度的高32位,nFileSizeLow是文件长度的低32位
这样照道理来说,不是要移32位吗。
高苗苗 发表于 2022-8-10 09:09
mxwawaawxm 发表于 2022-8-9 21:37
我找了个3.8G的文件试了一下。
nFileSizeHigh还是0
即便不移位,也是能得到正确大小

我搞错了,昨天没注意,UINT32最长能表达4GB的长度,所以,应该是找个超过4G的文件试下

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
mxwawaawxm + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| mxwawaawxm 发表于 2022-8-10 20:06
本帖最后由 mxwawaawxm 于 2022-8-10 22:24 编辑
高苗苗 发表于 2022-8-10 09:09
我搞错了,昨天没注意,UINT32最长能表达4GB的长度,所以,应该是找个超过4G的文件试下

谢谢。找了个6GB的文件测试。证明这样移位是错的

FileSize <<= sizeof(WORD)*8;

只移了16位,得这样写FileSize <<= 32;才能得到文件的正确大小。



您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-14 14:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表