C SetFilePointerEx获取文件大小

C SetFilePointerEx获取文件大小,c,winapi,C,Winapi,我是编程新手,尤其是Windows系统编程,我正在读一本相关的书。目前,我正在使用GetFileSizeEx玩arround,以获得文件的文件大小 我已经创建了这段代码,它一直工作到第65行,在那里我无法让SetFilePointerEx工作以获得大小 #include <Windows.h> #include <tchar.h> #include <stdio.h> #define BUFF_SIZE 0x100 // program to test f

我是编程新手,尤其是Windows系统编程,我正在读一本相关的书。目前,我正在使用GetFileSizeEx玩arround,以获得文件的文件大小

我已经创建了这段代码,它一直工作到第65行,在那里我无法让SetFilePointerEx工作以获得大小

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUFF_SIZE 0x100

// program to test file size

int _tmain(DWORD argc, LPTSTR argv[])
{
    HANDLE hIn;
    HANDLE hOut;
    LARGE_INTEGER liSize;
    LONG lSize, lDistance = 0;
    TCHAR szMsgGetFile[BUFF_SIZE];
    TCHAR szMsgSetFile[BUFF_SIZE];
    DWORD nIn;
    LARGE_INTEGER liPt;
    PLARGE_INTEGER pLi;
    pLi = &liPt;

    SecureZeroMemory(&liSize, sizeof(LARGE_INTEGER));
    SecureZeroMemory(&pLi, sizeof(LARGE_INTEGER));
    SecureZeroMemory(szMsgGetFile, _tcslen(szMsgGetFile));
    SecureZeroMemory(szMsgSetFile, _tcslen(szMsgSetFile));


    //get input and output handles
    hIn = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hIn == INVALID_HANDLE_VALUE)
        _tprintf(_T("[ERROR] CreateFile to get file input handle failed. Error code %d.\n"), GetLastError());
    hOut = CreateFile(_T("CONOUT$"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hOut == INVALID_HANDLE_VALUE)
        _tprintf(_T("[ERROR] CreateFile to get file output handle failed. Error code %d.\n"), GetLastError());

    //get the size of the file with GetFileSizeEx, acquired from hIn that is argv1
    if (!GetFileSizeEx(hIn, &liSize))
        _tprintf(_T("[ERROR] GetFileSizeEx failed. Error code %d\n"), GetLastError());

    //get the size of the file with SetFilePointer
    //You can obtain the file length by specifying a zero-length move from the end of
    //file, although the file pointer is changed as a side effect
    lSize = SetFilePointer(hIn, lDistance, NULL, FILE_END);
    if (lSize == INVALID_SET_FILE_POINTER)
        _tprintf(_T("[ERROR] SetFilePointer failed. Error code %d\n"), GetLastError());

    //output the size with WriteConsole (and sprintf)
    //and with _tprintf. Notice the usage of the liSize LARGE_INTEGER
    _stprintf_s(szMsgGetFile, BUFF_SIZE, "[*] GetFileSizeEx (WriteConsole): The size is %I64d Bytes.\n", liSize.QuadPart);
    if (!WriteConsole(hOut, szMsgGetFile, _tcslen(szMsgGetFile), &nIn, NULL))
        _tprintf(_T("[ERROR] WriteConsole failed. Error code %d\n"), GetLastError());
    _tprintf(_T("[*] GetFileSizeEx (tprintf): The size is %I64d Bytes.\n"), liSize.QuadPart);

    //output the size with WriteConsole (and sprintf)
    //and _tprintf
    _stprintf_s(szMsgSetFile, BUFF_SIZE, "[*] SetFilePointer (WriteConsole): The size is %ld Bytes.\n", lSize);
    if (!WriteConsole(hOut, szMsgSetFile, _tcslen(szMsgSetFile), &nIn, NULL))
        _tprintf(_T("[ERROR] WriteConsole failed. Error code %d\n"), GetLastError());
    _tprintf(_T("[*] SetFilePointer (tprintf): The size is %ld Bytes.\n"), lSize);

    //get the size of the file with SetFilePointerEx
    //Determine a file’s size by positioning 0 bytes from the end and using the file
    //pointer value returned by SetFilePointerEx.
    SecureZeroMemory(&liPt, sizeof(LARGE_INTEGER));
    SetFilePointerEx(hIn, liPt, pLi, FILE_END);
    _tprintf(_T("[*] SetFilePointerEx: %lld Bytes.\n"), pLi->QuadPart);
    return 0;
}
#包括
#包括
#包括
#定义BUFF_大小0x100
//测试文件大小的程序
整数(DWORD argc,LPTSTR argv[])
{
处理hIn;
处理hOut;
大整数线性化;
长lSize,lDistance=0;
TCHAR szMsgGetFile[BUFF_SIZE];
TCHAR szMsgSetFile[BUFF_SIZE];
德沃德·宁;
大整数liPt;
PLARGE_整数pLi;
pLi=&liPt;
SecureZeroMemory(&liSize,sizeof(大整数));
SecureZeroMemory(&pLi,sizeof(大整数));
SecureZeroMemory(szMsgGetFile,_tcslen(szMsgGetFile));
SecureZeroMemory(szMsgSetFile,_tcslen(szMsgSetFile));
//获取输入和输出句柄
hIn=CreateFile(argv[1],通用读取,文件共享读取,NULL,打开现有,文件属性正常,NULL);
if(hIn==无效的句柄值)
_tprintf(_T(“[ERROR]CreateFile以获取文件输入句柄失败。错误代码%d.\n”)、GetLastError();
hOut=CreateFile(_T(“CONOUT$”),泛型写,0,NULL,总是打开,文件属性,NULL);
if(hOut==无效的句柄值)
_tprintf(_T(“[ERROR]CreateFile以获取文件输出句柄失败。错误代码%d.\n”)、GetLastError();
//使用GetFileSizeEx获取文件的大小,该文件是从hIn获取的,即argv1
如果(!GetFileSizeEx(hIn,&liSize))
_tprintf(_T(“[ERROR]GetFileSizeEx失败。错误代码%d\n”)、GetLastError();
//使用SetFilePointer获取文件的大小
//通过指定从文件末尾开始的零长度移动,可以获得文件长度
//文件,尽管文件指针会因副作用而更改
lSize=SetFilePointer(hIn,lDistance,NULL,FILE_END);
if(lSize==无效的设置文件指针)
_tprintf(_T(“[ERROR]SetFilePointer失败。错误代码%d\n”)、GetLastError();
//使用WriteConsole(和sprintf)输出大小
//注意liSize大整数的用法
_stprintf_s(szMsgGetFile,BUFF_SIZE,“[*]GetFileSizeEx(writeconole):大小为%I64d字节。\n”,liSize.QuadPart);
if(!WriteConsole(hOut,szMsgGetFile,_tcslen(szMsgGetFile),&nIn,NULL))
_tprintf(_T(“[ERROR]WriteConsole失败。错误代码%d\n”)、GetLastError();
_tprintf(_T(“[*]GetFileSizeEx(tprintf):大小为%I64d字节。\n”)、liSize.QuadPart);
//使用WriteConsole(和sprintf)输出大小
//和
_stprintf_s(szMsgSetFile,BUFF_SIZE,“[*]SetFilePointer(WriteConsole):大小为%ld字节。\n”,lSize);
if(!WriteConsole(hOut,szMsgSetFile,_tcslen(szMsgSetFile),&nIn,NULL))
_tprintf(_T(“[ERROR]WriteConsole失败。错误代码%d\n”)、GetLastError();
_tprintf(_T(“[*]SetFilePointer(tprintf):大小为%ld字节。\n”),lSize);
//使用SetFilePointerEx获取文件的大小
//确定文件大小的方法是:从文件末尾开始放置0个字节并使用该文件
//SetFilePointerEx返回的指针值。
SecureZeroMemory(&liPt,sizeof(大整数));
SetFilePointerEx(hIn、liPt、pLi、文件结束);
_tprintf(_T(“[*]SetFilePointerEx:%lld字节。\n”)、pLi->QuadPart);
返回0;
}
MSDN说

您可以使用SetFilePointerEx来确定文件的长度。为此,请使用FILE_END for dwMoveMethod并查找位置零。返回的文件偏移量是文件的长度

但是,SetFilePointerEx属于BOOL类型。《Windows系统编程》一书中说,“通过从末尾定位0字节并使用SetFilePointerEx返回的文件指针值来确定文件大小。”。根据MSDN,我猜这个参数是
\u Out\u opt\u PLARGE\u整数lpNewFilePointer


我想获得有关如何使用SetFilePointerEx获取文件大小的帮助。

您的代码中有许多错误。下面是一个有效的
SetFilePointerEx
示例。通常,Win32函数不分配内存来存储它们的输出(有些是这样的)。由调用者分配内存。在这种情况下,通过将
size2
声明为
大整数来在堆栈上分配
SetFilePointerEx
输出的内存。然后将指向该
大整数的指针提供给
SetFilePointerEx

auto hIn = CreateFile(_T("C:\\foo"), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
/* check for errors */

LARGE_INTEGER size;
GetFileSizeEx(hIn, &size);
/* check for errors */

LARGE_INTEGER size2;
LARGE_INTEGER offset;
ZeroMemory(&offset, sizeof offset);
SetFilePointerEx(hIn, offset, &size2, FILE_END);
/* check for errors */

可选地,
DWORD dwFileSize=GetFileSize(hFile,NULL)
可以获取由
HANDLE hFile=CreateFileA/W(…)打开的文件的大小

我相信您在代码中使用的
SetFilePointerEx
是正确的。文件大小应该是
pLI->QuadPart
。你很快:)谢谢-事实上,在显示SetFilePointer tprintf输出后,我让程序崩溃了。当尝试调试它时(我不太会使用vs调试器),它会报告pLi为nullptrpLi为null。你从来没有设定过。请参阅我的答案以了解正确的方法。
SecureZeroMemory(&pLi,sizeof(大整数))这里有两个错误。首先,将pLi设置为零(在设置了pLi之后),第二次设置为零不需要
sizeof(大整数)
,而是
sizeof(大整数)
。那么这里根本就没有意义上的零变量。特别是使用SecureZeroMemoryy,您的代码可以正常工作,谢谢!如果你愿意,我想了解更多关于我的错误的信息。