我是编程新手,尤其是 Windows 系统编程,并且我正在阅读一本相关书籍。目前我正在玩 GetFileSizeEx,SetFilePointer和 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 是这么说的
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/