c - SetFilePointerEx 获取文件大小

标签 c winapi

我是编程新手,尤其是 Windows 系统编程,并且我正在阅读一本相关书籍。目前我正在玩 GetFileSizeEx,SetFilePointerSetFilePointerEx为了获取文件的文件大小。

我创建的这段代码一直工作到第 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;
}

MSDN 是这么说的

You can use SetFilePointerEx to determine the length of a file. To do this, use FILE_END for dwMoveMethod and seek to location zero. The file offset returned is the length of the file.

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

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

最佳答案

您的代码中有许多错误。下面是一个有效的 SetFilePointerEx 示例。一般来说,Win32 函数不会分配内存来存储其输出(有些函数会这样做)。由调用者来分配内存。在本例中,通过将 size2 声明为 LARGE_INTEGER,在堆栈上分配用于 SetFilePointerEx 输出的内存。然后,向 SetFilePointerEx 提供指向该 LARGE_INTEGER 的指针。

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 */

关于c - SetFilePointerEx 获取文件大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42563350/

相关文章:

c - execle() 函数中出现 errno 错误地址错误

挂钟的计算

c++ - 如何在 gdb 中观察复杂的对象?

c++ - 在 Qt4 应用程序中使用 user32.dll 中的函数

C++游戏训练器进程监控

c - 动态分配数组与使用全局作用域自动声明数组(C 语言)

python - 如何计算不同基数中数字的位数?

c# - Windows 8 中的 Metro 应用程序如何与同一台计算机上的后端桌面应用程序通信?

c++ - 游戏键盘输入和事件

winapi - 是否有任何 ui 自动化工具允许您更改/添加元素到窗口?