文件系统
一 windows卷
1
卷的获取
GetLogicalDrives() - 返回DWORD值,此值每位代表是否存在相应的卷
GetLogicalDriveStrings () -
获取所有卷盘符的字符串
DWORD GetLogicalDriveStrings( DWORD nBufferLength,//buff 大小 LPTSTR lpBuffer);//buff指针
Buff存放数据格式:
A:\ +0+ B:\ + 0 + C:\ + 0 ….. + 00
Windows的盘符A-Z(最多26个)
2卷的类型
UINGT GetDriveType(LPCTSTR lpRootPathName);//盘符
3卷的信息
BOOL GetVolumeInformationW( LPCTSTR lpRootPathName,//盘符 LPWSTR lpVolumeNameBuffer,///存放卷标的buff DWORD nVolumeNameSize,//存放卷标的buff长度 LPDWORD lpVolumeSerialNumber//卷的序列号, LPDWORD lpMaximumComponentLength,//路径最大字符串长度 LPDWORD lpFileSystemFlags,//文件系统标识 LPWSTR lpFileSystemNameBuffer,//文件系统名称buff DWORD nFileSystemNameSize//文件系统buff长度 );
4卷的大小
GetDiskFreeSpace -获取指定卷的大小(2GB以下)
BOOL GetDiskFreeSpaceA( LPCSTR lpRootPathName,//盘符 LPDWORD lpSectorsPerCluster,//每个簇包含的扇区 LPDWORD lpBytesPerSector,//每个扇区的字节数 LPDWORD lpNumberOfFreeClusters,//空余的簇的数量 LPDWORD lpTotalNumberOfClusters );//总共簇的数量
GetDiskFreeSpaceEx - 获取指定卷的大小(不限制)
GetDiskFreeSpaceExA( LPCSTR lpDirectoryName,//盘符 PULARGE_INTEGER lpFreeBytesAvailableToCaller,//可用空余字节数 PULARGE_INTEGER lpTotalNumberOfBytes,//全部字节数 PULARGE_INTEGER lpTotalNumberOfFreeBytes);//空余字节数
文件系统通过簇管理硬盘,每个簇由连续的几个扇区组成。
例如:1/2/4/8/16/32扇区构成一个簇
常见文件系统和簇的大小
FAT32 文件系统一个簇
= 8k字节
NTFS 文件系统一个簇
= 4k字节
簇是文件系统存放文件数据的最小单位,即使文件只有1B也需占用一个簇的空间
注意:簇的大小会根据磁盘大小变化,以上只是比较常见的簇大小
5
修改卷的名称
SetVolumnLable(LPCTSTR lpRootPahtName,//盘符 LPCTSTR lpVolumnName);//新名称
示例代码:
#include <Windows.h> #include <tchar.h> #include <stdio.h> void showSpace(LPSTR pszDrive) { DWORD nSectorPerCluster = 0; DWORD nBytesPerSector = 0; DWORD nFreeCluster = 0; DWORD nTotalCluster = 0; GetDiskFreeSpaceA(pszDrive, &nSectorPerCluster, &nBytesPerSector, &nFreeCluster, &nTotalCluster); printf("\tnSectorPerCluster = %d nBytesPerSector = %d nFreeCluster = %d nTotalCluster = %d\n", nSectorPerCluster, nBytesPerSector, nFreeCluster, nTotalCluster); UINT64 nFreeBytesAvailableToCaller = 0; UINT64 nTotalNumberOfBytes = 0; UINT64 nTotalNumberOfFreeBytes = 0; GetDiskFreeSpaceExA(pszDrive, (PULARGE_INTEGER)&nFreeBytesAvailableToCaller, (PULARGE_INTEGER)&nTotalNumberOfBytes, (PULARGE_INTEGER)&nTotalNumberOfFreeBytes); printf("\t nFreeBytesAvailableToCaller = %I64dM nTotalNumberOfBytes = %I64dM nTotalNumberOfFreeBytes = %I64dM \n", nFreeBytesAvailableToCaller>>20, nTotalNumberOfBytes>>20, nTotalNumberOfFreeBytes>>20); } void showType(LPSTR pszDrive) { UINT nType = GetDriveTypeA(pszDrive); switch (nType) { case DRIVE_FIXED: printf("硬盘\n"); break; case DRIVE_CDROM: printf("光驱\n"); break; case DRIVE_REMOVABLE: printf("移动\n"); break; } } void showVolumnInfo(LPSTR pszDrive) { char szVolumnName[260] = { 0 }; DWORD nVolumnSerial = 0; DWORD nMaxLength = 0; DWORD nFileSystem = 0; char szFileSystem[260] = { 0 }; GetVolumeInformationA(pszDrive, szVolumnName, 260, &nVolumnSerial, &nMaxLength, &nFileSystem, szFileSystem, 260); printf("\tName = %s Serial = %08x Length = %d FileSystem = %08x %s\n", szVolumnName, &nVolumnSerial, &nMaxLength,&nFileSystem, szFileSystem); } void showVolumn() { //获取系统卷位的标识 DWORD nDrivers = GetLogicalDrives(); printf("Drivers: %08x\n", nDrivers); char szText[256]; GetLogicalDriveStringsA(256,szText); //输出盘符 char *pszTemp = szText; while (0 != pszTemp[0]) { printf("Drivers: %s\n", pszTemp); showType(pszTemp); showVolumnInfo(pszTemp); showSpace(pszTemp); pszTemp = strlen(pszTemp) + 1 + pszTemp; } } int main() { showVolumn(); //设置卷标 //SetVolumeLabelA("C:\\", "System"); return 0; }
二目录
1
系统目录和当前目录
1.1获取系统目录
GetWindowsDirectory UINT GetWindowsDirectoryA( LPSTR lpBuffer,//buff地址 UINT uSize//buff长度 );
1.2获取System目录
GetSystemDirectory UINT GetSystemDirectoryA ( LPSTR lpBuffer,//buff地址 UINT uSize//buff长度 );
1.3获取临时文件路径
GetTempPath DWORD GetTempPathA( DWORD nBufferLength,//buff长度 LPSTR lpBuffer//buff地址 );
1.4当前目录
获取应用程序当前正在使用的默认目录
GetCurrentDirectory DWORD GetCurrentDirectoryA( DWORD nBufferLength,//buff长度 LPSTR lpBuffer//buff地址 )
设置应用程序当前正在使用的默认目录;
GetCurrentDirectory
DWORD GetCurrentDirectoryA( LPSTR lpBuffer//buff地址 )
2
目录的使用
2.1创建目录
CreateDirectory
BOOL CreateDirectoryA( LPCSTR lpPathName,//创建目录的路径 LPSECURITY_ATTRIBUTES lpSecurityAttributes//安全属性,默认为空 );
2.2删除目录(要删除的目录中必须为空目录)
RemoveDirectory
2.4修改目录名称
MoveFile
BOOL MoveFileA( LPCSTR lpExistingFileName,//旧名称 LPCSTR lpNewFileName//新名称 );
示例代码:
#include <Windows.h> #include <stdio.h> void useDirectory() { //创建目录 CreateDirectoryA("D:\\test", nullptr); //删除目录 //RemoveDirectoryA("D:\\test"); MoveFileA("D:\\test", "D:\\test1"); } void showDirectory() { //获取windows目录 char szWindow[MAX_PATH] = { 0 }; GetWindowsDirectoryA(szWindow, MAX_PATH); printf("windows directory = %s\n", szWindow); //获取system目录 char szSystem[MAX_PATH] = { 0 }; GetSystemDirectoryA(szSystem, MAX_PATH); printf("System dierctory = %s\n", szSystem); //获取临时文件路径 char szTempPath[MAX_PATH] = { 0 }; GetTempPathA(MAX_PATH, szTempPath); printf("TempPath = %s\n", szTempPath); char szCurrentDirectory[MAX_PATH] = { 0 }; GetCurrentDirectoryA(MAX_PATH, szCurrentDirectory); printf("CurrentDirectory = %s\n", szCurrentDirectory); SetCurrentDirectoryA("C:\\"); GetCurrentDirectoryA(MAX_PATH, szCurrentDirectory); printf("CurrentDirectory = %s\n", szCurrentDirectory); } int main() { showDirectory(); useDirectory(); return 0; }
三文件
1
文件创建/打开
CreateFile
HANDLE CreateFileA(//返回文件句柄 LPCSTR lpFileName,//文件路径和名称 DWORD dwDesiredAccess,//访问方式 DWORD dwShareMode,//共享模式 LPSECURITY_ATTRIBUTES lpSecurityAttributes,//安全属性,一般置空 DWORD dwCreationDisposition,//创建方式 DWORD dwFlagsAndAttributes,//文件属性 HANDLE hTemplateFile//拷贝文件句柄 );
2
文件关闭
Bool CloseHandle( HANDLE hObject);//要关闭的文件句柄
3
文件的数据写入
WriteFile BOOL WriteFile( HANDLE hFile,//文件句柄 LPCVOID lpBuffer,//写入数据的buff地址 DWORD nNumberOfBytesToWrite,//写入数据的buff长度 LPDWORD lpNumberOfBytesWritten,//返回被写入数据长度 LPOVERLAPPED lpOverLapped);//默认为空
4
文件的数据读取
BOOL ReadFile( HANDLE hFile,//文件句柄 LPVOID lpBuffer,//读入数据buff DWORD nNumberOfBytesToRead,//读入数据buff长度 LPDWORD lpNumberOfBytesRead,//返回读入数据长度 LPOVERLAPPED lpOverlapped// 默认为空 );
5获取文件长度
BOOL GetFileSizeEx( HANDLE hFile,//文件句柄 PLARGE_INTEGER lpFileSize//返回文件长度 );
6设置文件指针
DWORD SetFilePointer(//返回已偏移量的低32位 HANDLE hFile,//文件句柄 LONG lDistanceToMove,//准备偏移量 PLONG lpDistanceToMoveHigh,//已偏移量,高32位 DWORD dwMoveMethod//相对位置 );
7拷贝文件
BOOL CopyFileA( LPCSTR lpExistingFileName,//源文件 LPCSTR lpNewFileName,//目的文件 BOOL bFailIfExists//是否覆盖目的的同名文件,FALSE为 覆盖 );
8删除文件
BOOL DeleteFileA( LPCSTR lpFileName//要删除的文件名 );
9文件属性
9.1 GetFileAttributes - 获取文件属性
DWORD GetFileAttributesA(//返回文件的属性标识 LPCSTR lpFileName)//文件名
9.2 GetFileAttributesEx - 获取文件属性(增强版)
BOOL GetFileAttributesExA( LPCSTR lpFileName,//文件名 GET_FILEEX_INFO_LEVELS fInfoLevelId,//获取信息的级别 LPVOID lpFileInformation );//对应信息级别数据结构地址
9.3 SetFileAttributesA
DWORD SetFileAttributesA(//返回文件的属性标识 LPCSTR lpFileName//文件名 DWORD lpFileInformation属性标识 );
示例代码:
#include <Windows.h> #include <stdio.h> #include <stdlib.h> void Create() { //创建文件 HANDLE hFile = CreateFileA("D:\\file.txt", GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); //关闭文件 CloseHandle(hFile); } void Write() { //打开文件 HANDLE hFile = CreateFileA("D:\\file.txt", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); //写入数据 char szBuff[] = "Hello File!"; DWORD nWritten = 0; WriteFile(hFile, szBuff, strlen(szBuff), &nWritten, nullptr); //关闭文件 CloseHandle(hFile); } void Read() { //打开文件 HANDLE hFile = CreateFileA("D:\\file.txt", GENERIC_READ, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); UINT64 nSize = 0; //获取文件长度 //GetFileSizeEx(hFile,(PLARGE_INTEGER)&nSize); DWORD nHigh = 0; DWORD nLow = GetFileSize(hFile, &nHigh); nSize = MAKELONG(nLow,nHigh); //分配空间, char *pszBuf = (char*)malloc(sizeof(char)* (nLow + 1)); memset(pszBuf, 0, nLow + 1); //设置当前读取位置 SetFilePointer(hFile, 1, nullptr, FILE_BEGIN); //读取数据 DWORD nRead = 0; ReadFile(hFile, pszBuf, nLow + 1, &nRead, nullptr); printf("FILE = %s\n", pszBuf); //关闭文件 CloseHandle(hFile); } void Operate() { //拷贝文件 CopyFileA("d:\\file.txt", "d:\\file1.txt", FALSE); MoveFileA("d:\\file.txt", "d:\\file1.txt"); //删除文件 DeleteFileA("d:\\file.txt"); } void PrintFileTime(LPSTR pszName, LPFILETIME pFileItem) { FileTimeToLocalFileTime(pFileItem, pFileItem); //将文件时间转换为系统时间 SYSTEMTIME sysTime = { 0 }; FileTimeToSystemTime(pFileItem, &sysTime); printf("%s: %d-%d-%d %d-%d-%d\n", pszName, sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond); } void Attribute() { //获取文件的属性 DWORD nAttribute = GetFileAttributesA("D:\\file1.txt"); printf("Attribute = %08x\n", nAttribute); WIN32_FILE_ATTRIBUTE_DATA data = { 0 }; //获取文件的属性和信息 GetFileAttributesExA("D:\\file1.txt", GetFileExInfoStandard, &data); printf("attribute = %08x nFileSizeHigh = %d nFileSizeLow = %d \n ", data.dwFileAttributes, data.nFileSizeHigh, data.nFileSizeLow); PrintFileTime("CreateTime", &data.ftCreationTime); PrintFileTime("LastAccessTime", &data.ftLastAccessTime); PrintFileTime("LastWriteTime", &data.ftLastWriteTime); } int main() { FindNextFileA Operate(); Create(); Write(); Read(); Operate(); Attribute(); return 0; }
四文件的遍历和查找
1
查找文件
FindFirstFile
HANDLE FindFirstFileA(//返回查找句柄 LPCSTR lpFileName,//查找路径 LPWIN32_FIND_DATAA lpFindFileData//查找的文件信息 );
2
获取查找结果
FindNextFile
BOOL FindNextFileA(//查找成功,返回TRUE,否则返回FALSE HANDLE hFindFile,//查找句柄 LPWIN32_FIND_DATAA lpFindFileData//返回查找的信息 );
3
关闭查找
FindClose
Bool FileClose(//返回查找是否关闭成功 HANDLE hFindFile);//查找句柄
4
若要对查找结果按要求排序,需自己增加排序功能
示例代码:
#include <Windows.h> #include <stdio.h> #include <tchar.h> void Find(LPSTR path,LPSTR type) { char szFind[MAX_PATH] = { 0 }; sprintf_s(szFind, "%s%s", path, type); //开始查找 WIN32_FIND_DATAA data = { 0 }; HANDLE hFindFile = FindFirstFileA(szFind, &data); bool bet = true; //显示查找结果 while (bet) { if (data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { printf("[%s]\n", data.cFileName); if (data.cFileName[0] != '.') { //构造下级路径 char szNextPath[MAX_PATH] = { 0 }; sprintf_s(szNextPath, "%s%s\\", path, data.cFileName); //搜索下层目录 Find(szNextPath, type); } } else { printf("%s\n", data.cFileName); } bet = FindNextFileA(hFindFile, &data); } //关闭查找 FindClose(hFindFile); } int main() { Find("D:\\masm32\\","*.*");//查找路径和文件 return 0; }