第10章 内存管理和文件操作

1 内存管理

1.1 内存管理基础

标准内存管理函数
堆管理函数
虚拟内存管理函数
内存映射文件函数

windows内存管理api
各类内存函数操作的对象

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 返回堆中某个内存块的大小

虚拟内存管理

image.png

其它内存管理函数

RtlMoveMemory
RtlFillMemory
RtlZeroMemory
拷贝内存可以使用下面的汇编代码

复制内存

填充内存

内存置0

内存状态测试
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;
image.png

字符串函数

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 
   );

猜你喜欢

转载自blog.csdn.net/a854596855/article/details/114920049