2017-03-02 192 views
-1

我是編程新手,特別是在Windows系統編程中,我正在閱讀相關書籍。目前我正在玩GetFileSizeEx,SetFilePointerSetFilePointerEx以獲取文件的文件大小。SetFilePointerEx獲取文件大小

我已創建此代碼,直到第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確定文件的長度。爲此,使用FILE_END作爲dwMoveMethod並尋找位置零。返回的文件偏移量是文件的長度。

但是,SetFilePointerEx的類型是BOOL。 「Windows系統編程」一書指出,「通過從最後定位0字節並使用由SetFilePointerEx返回的文件指針值確定文件的大小」。我猜測這個參數是根據MSDN的_Out_opt_ PLARGE_INTEGER lpNewFilePointer

我想幫助如何使用SetFilePointerEx獲取文件的文件大小。

+1

我相信你在代碼中使用'SetFilePointerEx'是正確的。文件大小應該是'pLI-> QuadPart'。 –

+0

你很快:)謝謝 - 的確我有 – stukov

+0

該程序在顯示SetFilePointer tprintf輸出後崩潰。當試圖調試它(我是一個noob在使用VS調試器)它報告pLi是nullptr – stukov

回答

1

您的代碼中有許多錯誤。這裏有一個SetFilePointerEx的例子。一般來說,Win32函數不會分配內存來存儲它們的輸出(有些可以)。由調用者來分配內存。在這種情況下,SetFilePointerEx的輸出內存通過聲明size2LARGE_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 */ 
+0

您的代碼有效,謝謝!如果您願意,我想了解更多關於我的錯誤的信息。 – stukov

0

可選,DWORD dwFileSize = GetFileSize(hFile, NULL);可以得到由HANDLE hFile = CreateFileA/W(...);打開的文件的大小。