SetFilePointerEx获取文件大小

时间:2017-03-02 18:39:10

标签: 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说

  

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

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

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

2 个答案:

答案 0 :(得分:2)

您的代码中有许多错误。以下是SetFilePointerEx有效的示例。通常,Win32函数不会分配内存来存储它们的输出(有些)。由调用者来分配内存。在这种情况下,通过将SetFilePointerEx声明为size2,在堆栈上分配LARGE_INTEGER输出的内存。然后,指向LARGE_INTEGER的指针将提供给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 */

答案 1 :(得分:0)

或者,DWORD dwFileSize = GetFileSize(hFile, NULL);可以获得HANDLE hFile = CreateFileA/W(...);打开的文件大小。