5.静态加载
1)使用动态库的程序通过链接动态库的导入库(.lib)获得所需要调用的函数入口地址。
2)动态库需要放在如下位置:
A.可执行程序所在目录 - 推荐使用
B.当前工程目录下 - 依赖于开发环境,用于调试
C.WINDOWS目录下 \
D.WINDOWS/system32目录下 + 注意版本问题
E.WINDOWS/system目录下 /
F.PATH环境变量所包含的目录 - 依赖于系统环境
3)可执行程序一启动即加载所依赖的动态库,直到程序结束才卸载动态库。
6.动态加载(并不使用它的导入库)
HMODULE LoadLibrary (
LPCTSTR lpFileName // 动态库路径
);
成功返回动态库实例句柄,失败返回NULL。
FARPROC GetProcAddress (
HMODULE hModule, // 动态库实例句柄
LPCSTR lpProcName // 函数名
);
成功返回函数地址,失败返回NULL。
1)函数名需要考虑C++换名问题。
2)函数指针的类型问题。
BOOL FreeLibrary (
HMODULE hModule // 动态库实例句柄
);
成功返回TRUE,失败返回FALSE。
QQ在升级的时候需要退出,是因为它是使用的静态库加载,而如果使用动态库的话则不需要退出程序就可以在线升级。
1.工程名:LoadDLL
#include<windows.h>
#include<stdio.h>
int main(){
HMODULE hDLL=NULL;
hDLL=LoadLibrary("F:/Win32/Day14/Bin/CDll.dll");
if(hDLL==NULL)
fprintf(stderr,"加载动态库失败!%u\n",GetLastError());
FreeLibrary(hDLL);
return 0;
}
//打印出错误信息
void PrintLastError(LPCSTR pszTitle,BOOL bConsole=TRUE,HWND hWnd=NULL){
LPVOID pvErrMsg=NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),(LPSTR)&pvErrMsg,0,NULL);
if(bConsole)
fprintf(stderr,"%s:%s\n",pszTitle,(LPCSTR)pvErrMsg);
else
MessageBox(hWnd,(LPCSTR)pvErrMsg,pszTitle,MB_OK);
///释放
LocalFree(pvErrMsg);
}
///继续在main函数中, 获得函数地址
PFUNC2 pfunc=NULL;
if(!(pfunc=(PFUNC2)GetProcAddress(hDll,"c_mul"))){
PrintLastError("GetProcAddress出错");
return -1;
}
typedef int (*PFUNC2)(int ,int);
printf("%d*%d=%d\n",a,b,pfunc(a,b));
一、动态库的入口
动态库的入口不是必须的,常用于对动态库的内部状态做初始化。
BOOL WINAPI DllMain (
HANDLE hInstance, // 动态库实例句柄
DWORD dwReason, // 被调用原因
LPVOID lpvReserved // 保留
);
成功返回TRUE,失败返回FALSE。
dwReason取值:
DLL_PROCESS_ATTACH - 进程加载,主线程中调用LoadLibrary
DLL_PROCESS_DETACH - 进程卸载,主线程中调用FreeLibrary
DLL_THREAD_ATTACH - 线程加载,子线程中调用LoadLibrary
DLL_THREAD_DETACH - 线程卸载,子线程中调用FreeLibrary
/
动态库:DllMain
#include<windows.h>
#include<stdio.h>
#include "DllMain.h"
BOOL WINAPI DllMain(HANDLE hInstance,DWORD dwReason,LPVOID lpvReserved){
switch(dwReason){
case DLL_PROCESS_ATTACH:
printf("进程加载");
break;
case DLL_PROCESS_DETACH:
printf("进程卸载");
break;
}
return TRUE;
}
void hello(){
printf("你好,我是快乐的动态库");
}
/DllMain.h
#ifndef _DLLMAIN_H
#define _DLLMAIN_H
#ifdef DLLMAIN_EXPORTS
#define DLLMAIN_API _declspec(dllexport)
#else
#define DLLMAIN_API _declspec(dllimport)
#endif
DLLMAIN_API void hello(void);
#endif;
//写个程序加载下这个库
#include "../DLLMain/DllMain.h"
#pragma comment(lib,"../Lib/DllMain.lib")
int main(void){
hello();
return 0;
}
动态加载
#include "../DLLMain/DllMain.h"
//#pragma comment//(lib,"../Lib/DllMain.lib")
int main(void){
HMODULe hDll=LoadLibrary("DllMain.dll");
if(!hDll){
PrintLastError("LoadLibrary出错");
return -1;
}
PHELLO phello=(PHELLO)GetProcAddress(hDll,"?hello@@YAXXZ");
if(!phello){
PrintLastError("GetProcAddress出错");
}
phello();
FreeLibrary(hdll);
return 0;
}
C++函数中注意换名问题。这个名称哪里可以看到呢。暂时未知。有待以后查看。
/
二、Windows文件系统
Windows的常见文件系统:FAT、FAT32、NTFS
磁道:由若干扇区组成
扇区:512字节
固态硬盘:就是一个大U盘
文件系统的最小管理单位——簇——连续的若干扇区
FAT32:1簇=32扇区=16K字节
NTFS:1簇=8扇区=4K字节
文件存储是以簇为单位占用磁盘空间,即使只有1个字节,也要占用1个簇的磁盘空间。
三、目录APIs
1.获取磁盘驱动器信息
DWORD GetLogicalDrives (void);
返回当前可用逻辑驱动器的掩码。
L--------------------------------------------->H
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
HGFEDCBA ...KJI
0:无此逻辑驱动器
1:有此逻辑驱动器
DWORD表示32位,故可最多划分32个逻辑驱动器。使用小端方式存储。
///
WinDir.cpp
#include<windows.h>
#include<stdio.h>
int main(){
DWORD dwDrvs=GetLogicalDrives();
for(int i=0;i<sizeof(DWORD)*8,i++){
if(dwDrvs&1<<i)
printf("%c ",'A'+i);
printf("\n");
}
}
///
2.获取系统驱动器
DWORD GetLogicalDriveStrings (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
///
cout<<"系统驱动器:";
CHAR szSysDrv[256];
GetLogicalDriveStrings(sizeof(szSysDrv)/sizeof(szSysDrv[0]),szSysDrv);
cout<<szSysDrv;
3.获取当前目录
DWORD GetCurrentDirectory (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/
cout<<"原当前目录:";
CHAR szCurDir[MAX_PATH+1];//加'/0'
GetCurrentDirectory(sizeof(sszCurDir)/sizeof(szCurDir[0]),szCurDir);
cout<<szCurDir;
SetCurrentDirectory("C:/");
cout<<"新当前目录:";
GetCurrentDirectory(sizeof(sszCurDir)/sizeof(szCurDir[0]),szCurDir);
cout<<szCurDir;
4.设置当前目录
BOOL SetCurrentDirectory (
LPCTSTR lpPathName // 当前目录
);
成功返回TRUE,失败返回FALSE。
5.获取WINDOWS目录
UINT GetWindowsDirectory (
LPSTR lpBuffer, // 缓冲区指针
UINT uSize // 缓冲区大小(以字符为单位)
);
成功返回字符串长度,失败返回0。
6.获取系统(system32)目录
UINT GetSystemDirectory (
LPSTR lpBuffer, // 缓冲区指针
UINT uSize // 缓冲区大小(以字符为单位)
);
成功返回字符串长度,失败返回0。
//
printf ("WINDOWS目录:");
CHAR szWinDir[MAX_PATH+1];
GetWindowsDirectory (szWinDir,
sizeof (szWinDir) / sizeof (szWinDir[0]));
printf ("%s\n", szWinDir);
printf ("系统目录:");
CHAR szSysDir[MAX_PATH+1];
GetSystemDirectory (szSysDir,
sizeof (szSysDir) / sizeof (szSysDir[0]));
printf ("%s\n", szSysDir);
printf ("临时目录:");
CHAR szTempDir[MAX_PATH+1];
GetTempPath (sizeof (szTempDir) / sizeof (szTempDir[0]),szTempDir);
printf ("%s\n", szTempDir);
///
7.获取临时路径
DWORD GetTempPath (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
8.创建目录
BOOL CreateDirectory (
LPCTSTR lpPathName, // 目录路径
LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全属性,上层应用中置NULL
);
成功返回TRUE,失败返回FALSE。
9.移动目录
BOLL MoveFile (
LPCTSTR lpExistingFileName, // 原路径
LPCTSTR lpNewFileName // 新路径
);
成功返回TRUE,失败返回FALSE。
注意:不能跨逻辑驱动器移动目录,但是可以跨逻辑驱动器移动文件。
10.删除空目录
BOOL RemoveDirectory (
LPCTSTR lpPathName // 目录路径
);
成功返回TRUE,失败返回FALSE。
四、文件APIs
1.创建/打开文件
HANDLE CreateFile (
LPCTSTR lpFileName, // 文件路径
DWORD dwDesiredAccess, // 访问方式
DWORD dwShareMode, // 共享方式
... // 安全属性,NULL
DWORD dwCreationDisposition, // 创建或打开方式
DWORD dwFlagsAndAtrributes, // 文件属性
HANDLE hTemplateFile // 句柄模板(磁盘文件,设NULL)
);
成功返回文件句柄,失败返回INVALID_HANDLE_VALUE(-1)
dwDesiredAccess:
0 - 质询(判断文件是否存在)
GENERIC_READ - 读取
GENERIC_WRITE - 写入
dwShareMode:
FILE_SHARE_DELETE - 允许其它进程删除此文件
FILE_SHARE_READ - 允许其它进程读取此文件
FILE_SHARE_WRITE - 允许其它进程写入此文件
dwCreationDisposition:
CREATE_NEW - 不存在就创建,已存在就失败
CREATE_ALWAYS - 不存在就创建,已存在就删除原文件再创建
OPEN_EXISTING - 已存在就打开,不存在就失败
OPEN_ALWAYS - 已存在就打开,不存在就创建新文件再打开
TRUNCATE_EXISTING - 已存在就先清空再打开,不存在就失败
2.关闭文件
BOOL CloseHandle (
HANDLE handle // 内存对象句柄
);
成功返回TRUE,失败返回FALSE。
3.写入文件
BOOL WriteFile (
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer, // 数据缓冲区
DWORD nNumberOfBytesToWrite, // 期望写入的字节数
LPDWORD lpNumberOfBytesWritten, // 实际写入的字节数
LPOVERLAPPED lpOverlapped // 异步传输结构,可为NULL
);
成功返回TRUE,失败返回FALSE。
4.获取文件大小
DWORD GetFileSize (
HANDLE hFile, // 文件句柄
LPDWORD lpFileSizeHigh // 文件字节数的高32位
);
成功返回文件字节数的低32位。
32位 - 4G
64位 - 16G
5.读取文件
BOOL ReadFile (
HANDLE hFile, // 文件句柄
LPVOID lpBuffer, // 数据缓冲区
DWORD nNumberOfBytesToRead, // 期望读取的字节数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节数
LPOVERLAPPED lpOverlapped // 异步传输结构,可为NULL
);
成功返回TRUE,失败返回FALSE。
6.设置文件指针
DWORD SetFilePointer (
HANDLE hFile, // 文件句柄
LONG lDistanceToMove, // 偏移量的低32位
PLONG lpDistanceToMoveHigh, // 偏移量的高32位(输入输出)
DWORD dwMoveMethod // 偏移相对位置
);
返回文件指针新位置的低32位(高32位通过lpDistanceToMoveHigh输出)。
dwMoveMethod取值:
FILE_BEGIN
FILE_CURRENT
FILE_END
五、拷贝、移动、删除APIs
1.拷贝文件
BOOL CopyFile (
LPCTSTR lpExistingFileName, // 源路径
LPCTSTR lpNewFileName, // 目标路径
BOOL bFailIfExists // TRUE存在就失败,FALSE存在就覆盖
);
成功返回TRUE,失败返回FALSE。
2.移动文件
BOOL MoveFile (
LPCTSTR lpExistingFileName, // 原路径
LPCTSTR lpNewFileName // 新路径
);
成功返回TRUE,失败返回FALSE。
注意:不能跨逻辑驱动器移动目录,但是可以跨逻辑驱动器移动文件。
3.删除文件
BOOL DeleteFile (
LPCTSTR lpFileName // 路径
);
成功返回TRUE,失败返回FALSE。
1)使用动态库的程序通过链接动态库的导入库(.lib)获得所需要调用的函数入口地址。
2)动态库需要放在如下位置:
A.可执行程序所在目录 - 推荐使用
B.当前工程目录下 - 依赖于开发环境,用于调试
C.WINDOWS目录下 \
D.WINDOWS/system32目录下 + 注意版本问题
E.WINDOWS/system目录下 /
F.PATH环境变量所包含的目录 - 依赖于系统环境
3)可执行程序一启动即加载所依赖的动态库,直到程序结束才卸载动态库。
6.动态加载(并不使用它的导入库)
HMODULE LoadLibrary (
LPCTSTR lpFileName // 动态库路径
);
成功返回动态库实例句柄,失败返回NULL。
FARPROC GetProcAddress (
HMODULE hModule, // 动态库实例句柄
LPCSTR lpProcName // 函数名
);
成功返回函数地址,失败返回NULL。
1)函数名需要考虑C++换名问题。
2)函数指针的类型问题。
BOOL FreeLibrary (
HMODULE hModule // 动态库实例句柄
);
成功返回TRUE,失败返回FALSE。
QQ在升级的时候需要退出,是因为它是使用的静态库加载,而如果使用动态库的话则不需要退出程序就可以在线升级。
1.工程名:LoadDLL
#include<windows.h>
#include<stdio.h>
int main(){
HMODULE hDLL=NULL;
hDLL=LoadLibrary("F:/Win32/Day14/Bin/CDll.dll");
if(hDLL==NULL)
fprintf(stderr,"加载动态库失败!%u\n",GetLastError());
FreeLibrary(hDLL);
return 0;
}
//打印出错误信息
void PrintLastError(LPCSTR pszTitle,BOOL bConsole=TRUE,HWND hWnd=NULL){
LPVOID pvErrMsg=NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),(LPSTR)&pvErrMsg,0,NULL);
if(bConsole)
fprintf(stderr,"%s:%s\n",pszTitle,(LPCSTR)pvErrMsg);
else
MessageBox(hWnd,(LPCSTR)pvErrMsg,pszTitle,MB_OK);
///释放
LocalFree(pvErrMsg);
}
///继续在main函数中, 获得函数地址
PFUNC2 pfunc=NULL;
if(!(pfunc=(PFUNC2)GetProcAddress(hDll,"c_mul"))){
PrintLastError("GetProcAddress出错");
return -1;
}
typedef int (*PFUNC2)(int ,int);
printf("%d*%d=%d\n",a,b,pfunc(a,b));
一、动态库的入口
动态库的入口不是必须的,常用于对动态库的内部状态做初始化。
BOOL WINAPI DllMain (
HANDLE hInstance, // 动态库实例句柄
DWORD dwReason, // 被调用原因
LPVOID lpvReserved // 保留
);
成功返回TRUE,失败返回FALSE。
dwReason取值:
DLL_PROCESS_ATTACH - 进程加载,主线程中调用LoadLibrary
DLL_PROCESS_DETACH - 进程卸载,主线程中调用FreeLibrary
DLL_THREAD_ATTACH - 线程加载,子线程中调用LoadLibrary
DLL_THREAD_DETACH - 线程卸载,子线程中调用FreeLibrary
/
动态库:DllMain
#include<windows.h>
#include<stdio.h>
#include "DllMain.h"
BOOL WINAPI DllMain(HANDLE hInstance,DWORD dwReason,LPVOID lpvReserved){
switch(dwReason){
case DLL_PROCESS_ATTACH:
printf("进程加载");
break;
case DLL_PROCESS_DETACH:
printf("进程卸载");
break;
}
return TRUE;
}
void hello(){
printf("你好,我是快乐的动态库");
}
/DllMain.h
#ifndef _DLLMAIN_H
#define _DLLMAIN_H
#ifdef DLLMAIN_EXPORTS
#define DLLMAIN_API _declspec(dllexport)
#else
#define DLLMAIN_API _declspec(dllimport)
#endif
DLLMAIN_API void hello(void);
#endif;
//写个程序加载下这个库
#include "../DLLMain/DllMain.h"
#pragma comment(lib,"../Lib/DllMain.lib")
int main(void){
hello();
return 0;
}
动态加载
#include "../DLLMain/DllMain.h"
//#pragma comment//(lib,"../Lib/DllMain.lib")
int main(void){
HMODULe hDll=LoadLibrary("DllMain.dll");
if(!hDll){
PrintLastError("LoadLibrary出错");
return -1;
}
PHELLO phello=(PHELLO)GetProcAddress(hDll,"?hello@@YAXXZ");
if(!phello){
PrintLastError("GetProcAddress出错");
}
phello();
FreeLibrary(hdll);
return 0;
}
C++函数中注意换名问题。这个名称哪里可以看到呢。暂时未知。有待以后查看。
/
二、Windows文件系统
Windows的常见文件系统:FAT、FAT32、NTFS
磁道:由若干扇区组成
扇区:512字节
固态硬盘:就是一个大U盘
文件系统的最小管理单位——簇——连续的若干扇区
FAT32:1簇=32扇区=16K字节
NTFS:1簇=8扇区=4K字节
文件存储是以簇为单位占用磁盘空间,即使只有1个字节,也要占用1个簇的磁盘空间。
三、目录APIs
1.获取磁盘驱动器信息
DWORD GetLogicalDrives (void);
返回当前可用逻辑驱动器的掩码。
L--------------------------------------------->H
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
HGFEDCBA ...KJI
0:无此逻辑驱动器
1:有此逻辑驱动器
DWORD表示32位,故可最多划分32个逻辑驱动器。使用小端方式存储。
///
WinDir.cpp
#include<windows.h>
#include<stdio.h>
int main(){
DWORD dwDrvs=GetLogicalDrives();
for(int i=0;i<sizeof(DWORD)*8,i++){
if(dwDrvs&1<<i)
printf("%c ",'A'+i);
printf("\n");
}
}
///
2.获取系统驱动器
DWORD GetLogicalDriveStrings (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
///
cout<<"系统驱动器:";
CHAR szSysDrv[256];
GetLogicalDriveStrings(sizeof(szSysDrv)/sizeof(szSysDrv[0]),szSysDrv);
cout<<szSysDrv;
3.获取当前目录
DWORD GetCurrentDirectory (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/
cout<<"原当前目录:";
CHAR szCurDir[MAX_PATH+1];//加'/0'
GetCurrentDirectory(sizeof(sszCurDir)/sizeof(szCurDir[0]),szCurDir);
cout<<szCurDir;
SetCurrentDirectory("C:/");
cout<<"新当前目录:";
GetCurrentDirectory(sizeof(sszCurDir)/sizeof(szCurDir[0]),szCurDir);
cout<<szCurDir;
4.设置当前目录
BOOL SetCurrentDirectory (
LPCTSTR lpPathName // 当前目录
);
成功返回TRUE,失败返回FALSE。
5.获取WINDOWS目录
UINT GetWindowsDirectory (
LPSTR lpBuffer, // 缓冲区指针
UINT uSize // 缓冲区大小(以字符为单位)
);
成功返回字符串长度,失败返回0。
6.获取系统(system32)目录
UINT GetSystemDirectory (
LPSTR lpBuffer, // 缓冲区指针
UINT uSize // 缓冲区大小(以字符为单位)
);
成功返回字符串长度,失败返回0。
//
printf ("WINDOWS目录:");
CHAR szWinDir[MAX_PATH+1];
GetWindowsDirectory (szWinDir,
sizeof (szWinDir) / sizeof (szWinDir[0]));
printf ("%s\n", szWinDir);
printf ("系统目录:");
CHAR szSysDir[MAX_PATH+1];
GetSystemDirectory (szSysDir,
sizeof (szSysDir) / sizeof (szSysDir[0]));
printf ("%s\n", szSysDir);
printf ("临时目录:");
CHAR szTempDir[MAX_PATH+1];
GetTempPath (sizeof (szTempDir) / sizeof (szTempDir[0]),szTempDir);
printf ("%s\n", szTempDir);
///
7.获取临时路径
DWORD GetTempPath (
DWORD nBufferLength, // 缓冲区大小(以字符为单位)
LPTSTR lpBuffer // 缓冲区指针
);
成功返回字符串长度,失败返回0。
8.创建目录
BOOL CreateDirectory (
LPCTSTR lpPathName, // 目录路径
LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全属性,上层应用中置NULL
);
成功返回TRUE,失败返回FALSE。
9.移动目录
BOLL MoveFile (
LPCTSTR lpExistingFileName, // 原路径
LPCTSTR lpNewFileName // 新路径
);
成功返回TRUE,失败返回FALSE。
注意:不能跨逻辑驱动器移动目录,但是可以跨逻辑驱动器移动文件。
10.删除空目录
BOOL RemoveDirectory (
LPCTSTR lpPathName // 目录路径
);
成功返回TRUE,失败返回FALSE。
四、文件APIs
1.创建/打开文件
HANDLE CreateFile (
LPCTSTR lpFileName, // 文件路径
DWORD dwDesiredAccess, // 访问方式
DWORD dwShareMode, // 共享方式
... // 安全属性,NULL
DWORD dwCreationDisposition, // 创建或打开方式
DWORD dwFlagsAndAtrributes, // 文件属性
HANDLE hTemplateFile // 句柄模板(磁盘文件,设NULL)
);
成功返回文件句柄,失败返回INVALID_HANDLE_VALUE(-1)
dwDesiredAccess:
0 - 质询(判断文件是否存在)
GENERIC_READ - 读取
GENERIC_WRITE - 写入
dwShareMode:
FILE_SHARE_DELETE - 允许其它进程删除此文件
FILE_SHARE_READ - 允许其它进程读取此文件
FILE_SHARE_WRITE - 允许其它进程写入此文件
dwCreationDisposition:
CREATE_NEW - 不存在就创建,已存在就失败
CREATE_ALWAYS - 不存在就创建,已存在就删除原文件再创建
OPEN_EXISTING - 已存在就打开,不存在就失败
OPEN_ALWAYS - 已存在就打开,不存在就创建新文件再打开
TRUNCATE_EXISTING - 已存在就先清空再打开,不存在就失败
2.关闭文件
BOOL CloseHandle (
HANDLE handle // 内存对象句柄
);
成功返回TRUE,失败返回FALSE。
3.写入文件
BOOL WriteFile (
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer, // 数据缓冲区
DWORD nNumberOfBytesToWrite, // 期望写入的字节数
LPDWORD lpNumberOfBytesWritten, // 实际写入的字节数
LPOVERLAPPED lpOverlapped // 异步传输结构,可为NULL
);
成功返回TRUE,失败返回FALSE。
4.获取文件大小
DWORD GetFileSize (
HANDLE hFile, // 文件句柄
LPDWORD lpFileSizeHigh // 文件字节数的高32位
);
成功返回文件字节数的低32位。
32位 - 4G
64位 - 16G
5.读取文件
BOOL ReadFile (
HANDLE hFile, // 文件句柄
LPVOID lpBuffer, // 数据缓冲区
DWORD nNumberOfBytesToRead, // 期望读取的字节数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节数
LPOVERLAPPED lpOverlapped // 异步传输结构,可为NULL
);
成功返回TRUE,失败返回FALSE。
6.设置文件指针
DWORD SetFilePointer (
HANDLE hFile, // 文件句柄
LONG lDistanceToMove, // 偏移量的低32位
PLONG lpDistanceToMoveHigh, // 偏移量的高32位(输入输出)
DWORD dwMoveMethod // 偏移相对位置
);
返回文件指针新位置的低32位(高32位通过lpDistanceToMoveHigh输出)。
dwMoveMethod取值:
FILE_BEGIN
FILE_CURRENT
FILE_END
五、拷贝、移动、删除APIs
1.拷贝文件
BOOL CopyFile (
LPCTSTR lpExistingFileName, // 源路径
LPCTSTR lpNewFileName, // 目标路径
BOOL bFailIfExists // TRUE存在就失败,FALSE存在就覆盖
);
成功返回TRUE,失败返回FALSE。
2.移动文件
BOOL MoveFile (
LPCTSTR lpExistingFileName, // 原路径
LPCTSTR lpNewFileName // 新路径
);
成功返回TRUE,失败返回FALSE。
注意:不能跨逻辑驱动器移动目录,但是可以跨逻辑驱动器移动文件。
3.删除文件
BOOL DeleteFile (
LPCTSTR lpFileName // 路径
);
成功返回TRUE,失败返回FALSE。