第10章 内存管理和文件操作
1 内存管理
1.1 内存管理基础
标准内存管理函数
堆管理函数
虚拟内存管理函数
内存映射文件函数


GlobalMemoryStatus 获取系统的内存使用状态
1 固定的内存块
GlobalAlloc 申请 需要指定flag GMEM_FIXED
GlobalFree 释放
GlobalReAlloc 变更大小
2 可移动的内存块
操作系统会进行碎片整理
GlobalAlloc 申请 需要指定flag GMEM_MOVEABLE 会返回一个内存句柄
使用的时候要进行锁定
GlobalLock 会返回一个内存地址
暂时不需要使用时可以解锁
GlobalUnlock
释放
GlobalFree
调整大小
GlobalReAlloc
win32下已经不支持内存移动了
3 可丢弃的内存块
GMEM_MOVEABLE GMEM_DISCARDABLE
表示 操作系统在急需内存时可以将这块内存从物理内存中丢弃
GlobalDiscard
堆管理函数
操作私有堆 不同的线程可以在不同的私有堆中操作内存
1 私有堆的申请和释放
HeapCreate
HeapDestroy
GetProcessHeap
HeapAlloc
HeapFree
HeapReAlloc
GetProcessHeaps 列出进程中所有的堆
HeapWalk 列出一个堆上所有的内存块
HeapValidate 检验一个堆中所有内存块的有效性
HeapLock 锁定堆
HeapUnlock 解锁堆
HeapCompact 合并堆中的空闲内存块
HeapSize 返回堆中某个内存块的大小
虚拟内存管理

其它内存管理函数
RtlMoveMemory
RtlFillMemory
RtlZeroMemory
拷贝内存可以使用下面的汇编代码

填充内存

内存状态测试
IsBadCodePtr
IsBadReadPtr
IsBadWritePtr
IsBadStringPtr
2 文件操作
文件句柄和读写指针
- 文件函数的操作对象包括 文件、串口、磁盘设备、网络文件、控制 台和目录等
- 支持异步文件操作
- 文件的共享和锁定
- 内存映射文件
- 拷贝文件和移动文件
文件名长度<=255
不合法的文件名字符
/\:*?"<>|
NTFS 文件系统 支持对文件进行访问控制
CreateFile
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode GENERIC_READ | GENERIC_WRITE
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
CloseHandle
BOOL CloseHandle(
HANDLE hObject // handle to object to close
);
设置文件指针
DWORD SetFilePointer(
HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh, // address of high-order word of distance to move
DWORD dwMoveMethod // how to move
);
返回移动后的文件指针
invoke SetFilePointer,hFile,0,NULL,FILE_CURRENT
可获取当前的文件指针
SetEndOfFile 用来截断文件
文件的读写
BOOL ReadFile(
HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // address of buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read 要读取的字节数
LPDWORD lpNumberOfBytesRead, // address of number of bytes read 实际读取到的字节数
LPOVERLAPPED lpOverlapped // address of structure for data
);
BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
将缓冲区中的数据立即写入文件
BOOL FlushFileBuffers(
HANDLE hFile // open handle to file whose buffers are to be flushed
);
文件的共享
对文件的某一部分加锁
BOOL LockFile(
HANDLE hFile, // handle of file to lock
DWORD dwFileOffsetLow, // low-order word of lock region offset
DWORD dwFileOffsetHigh, // high-order word of lock region offset
DWORD nNumberOfBytesToLockLow, // low-order word of length to lock
DWORD nNumberOfBytesToLockHigh // high-order word of length to lock
);
解锁
BOOL UnlockFile(
HANDLE hFile, // handle of file to unlock
DWORD dwFileOffsetLow, // low-order word of lock region offset
DWORD dwFileOffsetHigh, // high-order word of lock region offset
DWORD nNumberOfBytesToUnlockLow, // low-order word of length to unlock
DWORD nNumberOfBytesToUnlockHigh // high-order word of length to unlock
);
查找文件
HANDLE FindFirstFile(
LPCTSTR lpFileName, // pointer to name of file to search for
LPWIN32_FIND_DATA lpFindFileData // pointer to returned information
);
BOOL FindNextFile(
HANDLE hFindFile, // handle to search
LPWIN32_FIND_DATA lpFindFileData // pointer to structure for data on found file
);
BOOL FindClose(
HANDLE hFindFile // file search handle
);
typedef struct _WIN32_FIND_DATA { // wfd
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
TCHAR cFileName[ MAX_PATH ]; //文件名,不包括路径名
TCHAR cAlternateFileName[ 14 ]; //8.3结构的短文件名
} WIN32_FIND_DATA;

字符串函数
lstrcpy
lstrcat
文件的属性
获取文件类型
DWORD GetFileType(
HANDLE hFile // file handle
);
4种类型
FILE_TYPE_UNKNOWN The type of the specified file is unknown.
FILE_TYPE_DISK The specified file is a disk file.
FILE_TYPE_CHAR The specified file is a character file, typically an LPT device or a console.
FILE_TYPE_PIPE The specified file is either a named or anonymous pipe.
获取文件长度
DWORD GetFileSize(
HANDLE hFile, // handle of file to get size of
LPDWORD lpFileSizeHigh // address of high-order word for file size
);
返回长度的低32位
获取文件时间
BOOL GetFileTime(
HANDLE hFile, // identifies the file
LPFILETIME lpCreationTime, // address of creation time 创建时间
LPFILETIME lpLastAccessTime, // address of last access time 最后访问时间
LPFILETIME lpLastWriteTime // address of last write time 最后写入时间
);
typedef struct _FILETIME { // ft
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME;
将FILETIME拷入LARGE_INTEGER共用体
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
//将文件时间转化为系统时间
BOOL FileTimeToSystemTime(
CONST FILETIME *lpFileTime, // pointer to file time to convert
LPSYSTEMTIME lpSystemTime // pointer to structure to receive system time
);
//设置文件时间
BOOL SetFileTime(
HANDLE hFile, // identifies the file
CONST FILETIME *lpCreationTime, // time the file was created
CONST FILETIME *lpLastAccessTime, // time the file was last accessed
CONST FILETIME *lpLastWriteTime // time the file was last written
);
BOOL SystemTimeToFileTime(
CONST SYSTEMTIME *lpSystemTime, // address of system time to convert
LPFILETIME lpFileTime // address of buffer for converted file time
);
DWORD GetFileAttributes(
LPCTSTR lpFileName // address of the name of a file or directory
);
BOOL SetFileAttributes(
LPCTSTR lpFileName, // address of filename
DWORD dwFileAttributes // address of attributes to set
);
拷贝文件
BOOL CopyFile(
LPCTSTR lpExistingFileName, // pointer to name of an existing file
LPCTSTR lpNewFileName, // pointer to filename to copy to
BOOL bFailIfExists // flag for operation if file exists
);
移动文件
BOOL MoveFile(
LPCTSTR lpExistingFileName, // address of name of the existing file
LPCTSTR lpNewFileName // address of new name for the file
);
MoveFileEx
删除文件
BOOL DeleteFile(
LPCTSTR lpFileName // pointer to name of file to delete
);
3 驱动器和目录

逻辑驱动器操作
修改和删除卷标 c d e f 的名称
BOOL SetVolumeLabel(
LPCTSTR lpRootPathName, // address of name of root directory for volume
LPCTSTR lpVolumeName // name for the volume
);
检查逻辑驱动器是否存在 返回的32位整数,表示 A-Z是否存在
DWORD GetLogicalDrives(VOID)
返回存在的逻辑驱动器的字符串 如"C:\",0,"D:\",0
DWORD GetLogicalDriveStrings(
DWORD nBufferLength, // size of buffer
LPTSTR lpBuffer // address of buffer for drive strings
);
获取驱动器类型
UINT GetDriveType(
LPCTSTR lpRootPathName // address of root path
);
返回值
0 The drive type cannot be determined.
1 The root directory does not exist.
DRIVE_REMOVABLE The drive can be removed from the drive.
DRIVE_FIXED The disk cannot be removed from the drive.
DRIVE_REMOTE The drive is a remote (network) drive.
DRIVE_CDROM The drive is a CD-ROM drive.
DRIVE_RAMDISK The drive is a RAM disk.
获取卷的详细信息
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName, // address of root directory of the file system
LPTSTR lpVolumeNameBuffer, // address of name of the volume
DWORD nVolumeNameSize, // length of lpVolumeNameBuffer
LPDWORD lpVolumeSerialNumber, // address of volume serial number
LPDWORD lpMaximumComponentLength, // address of system's maximum filename length
LPDWORD lpFileSystemFlags, // address of file system flags
LPTSTR lpFileSystemNameBuffer, // address of name of file system
DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer
);
获取驱动器空闲空间
BOOL GetDiskFreeSpace(
LPCTSTR lpRootPathName, // address of root path
LPDWORD lpSectorsPerCluster, // address of sectors per cluster 每簇的扇区数
LPDWORD lpBytesPerSector, // address of bytes per sector 每个扇区的字节数
LPDWORD lpNumberOfFreeClusters, // address of number of free clusters 空闲的簇 数
LPDWORD lpTotalNumberOfClusters // address of total number of clusters 簇的总数
);
目录操作
创建目录
BOOL CreateDirectory(
LPCTSTR lpPathName, // pointer to a directory path string
LPSECURITY_ATTRIBUTES lpSecurityAttributes // pointer to a security descriptor
);
删除目录
BOOL RemoveDirectory(
LPCTSTR lpPathName // address of directory to remove
);
windows系统中的特殊目录
- 当前目录
- windows目录 windows系统的安装目录
- 系统目录 windows系统中安装目录下存放系统文件的目录 system32
- 临时目录 存放临时文件的目录
DWORD GetCurrentDirectory(
DWORD nBufferLength, // size, in characters, of directory buffer
LPTSTR lpBuffer // address of buffer for current directory
);
DWORD GetTempPath(
DWORD nBufferLength, // size, in characters, of the buffer
LPTSTR lpBuffer // address of buffer for temp. path
);
UINT GetWindowsDirectory(
LPTSTR lpBuffer, // address of buffer for Windows directory
UINT uSize // size of directory buffer
);
UINT GetSystemDirectory(
LPTSTR lpBuffer, // address of buffer for system directory
UINT uSize // size of directory buffer
);
BOOL SetCurrentDirectory(
LPCTSTR lpPathName // address of name of new current directory
);
4 内存映射文件
是win32中最有实用价值的新特征之一,使得程序访问文件如同访问内存一样,可用于不同的程序共享内存


使用内存映射

step 1
创建内存映射
HANDLE CreateFileMapping(
HANDLE hFile, // handle to file to map 若用于进程间通信这个参数为-1
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // optional security attributes 用来表示句柄是否被继承
DWORD flProtect, // protection for mapping object 保护类型
DWORD dwMaximumSizeHigh, // high-order 32 bits of object size
DWORD dwMaximumSizeLow, // low-order 32 bits of object size 指定大小 进程间通信为0
LPCTSTR lpName // name of file-mapping object 用于进程间通信的话必须设置
);
打开映射文件
HANDLE OpenFileMapping(
DWORD dwDesiredAccess, // access mode FILE_MAP_READ FILE_MAP_WRITE FILE_MAP_COPY
BOOL bInheritHandle, // inherit flag
LPCTSTR lpName // pointer to name of file-mapping object
);
step 2 映射文件
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // file-mapping object to map into address space
DWORD dwDesiredAccess, // access mode
DWORD dwFileOffsetHigh, // high-order 32 bits of file offset
DWORD dwFileOffsetLow, // low-order 32 bits of file offset 映射的起始位置
DWORD dwNumberOfBytesToMap // number of bytes to map 映射的数据大小为 0的话,映射整个文件
);
会返回一个地址,用该地址就可以存取文件
使用结束后
取消映射
BOOL UnmapViewOfFile(
LPCVOID lpBaseAddress // address where mapped view begins
);
使用CloseHandle关闭内存映射句柄
将内存映射的内容立即写入磁盘
BOOL FlushViewOfFile(
LPCVOID lpBaseAddress, // start address of byte range to flush
DWORD dwNumberOfBytesToFlush // number of bytes in range
);