在VC下文件的使用的案例
文件常用的有新建,读,写文件,删除文件,读取文件的路径,创建文件夹(目录),文件的复制,移动,重命名,读取文件的大小,
查找文件,遍历目录下的文件和子目录,递归遍历目录下的所有文件和子目录
比较少用到的的功能设置文件的属性,使用内存映射文件等
下面是几个关于文件使用几个函数 :
#include
#include
//创建文件
HANDLE CreateFile( __in LPCSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile );
//参数
//lpFileName //操作对象文件的相对或者绝对路径
//dwDesiredAccess //指明对象文件的操作存取方式 GENERIC_READ, GENERIC_WRITE, GENERIC_READGENERIC_WRITE
//dwShareMode //指明与其他进程是否共享该文件,可以读,写,删除共享等FILE_SHARE_WRITE, 如果进程独占改文件,设置为0
//lpSecurityAttributes //表示文件句柄的安全属性,一般设置为NULL,有特殊要求特别设置
//dwCreationDisposition //文件操作模式 CREATE_ALWAYS, CREATE_NEW, OPEN_ALWAYS, OPEN_EXISTING, TRUNCATE_EXISTING
//dwFlagsAndAttributes //文件属性和标志, 一般设置为FILE_ATTRIBUTE_NORMAL
//hTemplateFile //当存取权限包括GENERIC_WRITE, 可以设置一个模板文件的句柄.一般设置为NULL
HANDLE hFile = CreateFile(".\\setting.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//从文件中读取数据
BOOL ReadFile(__in HANDLE hFile,
__out_bcount_part_opt(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped);
//参数
//hFile 文件句柄,文件操作方式应该是GENERIC_READ
//lpBuffer 读取文件数据存储数据的内存缓冲区
//nNumberOfBytesToRead 指明需要需要从文件中读出的数据的大小,不能大于lpBuffer的大小,否则会溢出
//lpNumberOfBytesRead输出参数,指向存储实际独处的数据大小DWORD变量
//lpOverlapped:输出参数,如果抵用CreateFile函数设置了FILE_FLAG_OVERLAPPED标志,则需要使用该参数,否则可以为NULL
//从文件中写入数据
BOOL WriteFile( __in HANDLE hFile,
__in_bcount_opt(nNumberOfBytesToWrite) LPCVOID lpBuffer,
__in DWORD nNumberOfBytesToWrite,
__out_opt LPDWORD lpNumberOfBytesWritten,
__inout_opt LPOVERLAPPED lpOverlapped );
//参数
//hFile 文件句柄
//lpBuffer 需要写入文件的缓冲区
//nNumberOfBytesToWrite 指明需要写入文件中的数据的大小
//lpNumberOfBytesWritten 指向真是写入的数据大小的变量
//lpOverlapped:输出参数,如果抵用CreateFile函数设置了FILE_FLAG_OVERLAPPED标志,则需要使用该参数,否则可以为NULL
//获取文件的大小
DWORD GetFileSize(HANDLE hFile, LPDWORD lpFilesizeHigh);
//参数
//HANDLE hFile 文件句柄
//LPDWORD lpFilesizeHigh 输出函数, 表示得到的文件大小的高32位,该参数可以设置为NULL
//还有一个获取文件大小的函数 BOOL GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
//删除文件
BOOL DeleteFile( LPCTSTR lpFileName );
//参数 LPCTSTR lpFileName 表示要删除文件的相对路径或绝对路径
//返回值BOOL 表示文件删除是否成功,如果程序返回失败,可以用GetLastError()获取错误信息
//复制文件
BOOL CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists);
//参数
//lpExistingFileName : 已经存在的所需复制文件的原路径
//lpNewFilename : 新文件路径,复制文件的目的路径
//bFailIfExists : 指明如果在目的路径存在文件时是否覆盖,如果设置为TRUE,则不覆盖,如果存在,则返回失败(0x50)
//移动文件(该函数的功能 : 移动,重命名和目录)
BOOL MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName);
//参数
//lpExistingFileName : 已经存在的所需移动文件的原路径
//lpNewFilename : 新文件路径,移动文件的目的路径
//CopyFileEx, MoveFileEx, MoveFileWithProcessSS函数功能更加丰富
//创建一个目录或者文件夹
BOOL CreateDirectory( LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes );
//lpPathName : 所需要创建的目录或者路径
//lpSecurityAttributes : 输入参数,设置为NULL
//返回值 如果失败,可以使用GetLastError函数获取错误信息,
//可能的值包括ERROR_ALREADY_EXISTS(文件已经存在), ERROR_PATH_NOT_FOUND
//获取进程的当前目录
DWORD GetCurrentDirectory( DWORD nBufferLength, LPTSTR lpBuffer );
//参数
//nBufferLength : 输入参数,存储路径字符串缓冲区的大小,一般调用MAX_PATH
//lpBuffer: 输出参数,只想获取的路径字符串
//返回值 : 如果为0,表示失败。 如果非0,表示获取的字符串的长度
//设置进程的当前目录
BOOL SetCurrentDirectory(LPCTSTR lpPathName);
//参数
//lpPathName : 输入参数,所要设置的路径
//获取模块文件名
DWORD GetModuleFileName( __in_opt HMODULE hModule,
__out_ecount_part(nSize, return + 1) LPSTR lpFilename,
__in DWORD nSize );
//hModule : 所需要模块路径的模块句柄,设置为NULL表示当前模块路径
//lpFilename: 模块的全路径
//nSize : 指向缓冲区的大小
//返回值 : 如果为0,表示失败。 如果非0,表示获取的字符串的长度
//对文件进行查找,遍历指定目录下的文件和子目录
//WINDOW api中,有一组专门的函数和数据结构,用于遍历目录,
//他们是FindFirstFile, FindNextFile, WIN32_FIND_DATA
BOOL FindNextFile( __in HANDLE hFindFile,
__out LPWIN32_FIND_DATAA lpFindFileData );
//hFindFile 查找的目录,需使用通配符指定查找的文件目标
//lpFindFileData 指向WIN32_FIND_DATA结构的指针,为找到的文件及若干属性信息
HANDLE FindFirstFile( __in LPCSTR lpFileName,
__out LPWIN32_FIND_DATAA lpFindFileData );
//lpFileName 查找句柄
//lpFindFileData 指向WIN32_FIND_DATA结构的指针,为找到的文件及若干属性信息
//关键的结构体
typedef struct _WIN32_FIND_DATAA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
CHAR cFileName[ MAX_PATH ];
CHAR cAlternateFileName[ 14 ];
#ifdef _MAC
DWORD dwFileType;
DWORD dwCreatorType;
WORD wFinderFlags;
#endif
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
//实现对指定目录中文件和子目录的遍历,并将遍历得到的文件和其他属性打印到界面上
DWORD EnumerateFileInDirectory(LPSTR szPath)
{
WIN32_FIND_DATA FindFileData;
HANDLE hListFile;
CHAR szFilePath[MAX_PATH];
//构造代表子目录和文件夹路径的字符串,使用通配符"*"
lstrcpy(szFilePath, szPath);
//注释的代码可以用于查找所有的以".txt"结尾的文件
//lstrcat(szFilePath, "\\*.txt");
lstrcat(szFilePath, "\\*");
//查找第一个文件/目录, 获取查找句柄
hListFile = FindFirstFile(szFilePath, &FindFileData);
if (hListFile == INVALID_HANDLE_VALUE)
{
return 1;
}
else
{
do
{
/*如果不想显示代表本级目录和上一级目录的"."和".."
可以使用注释部分的代码过滤
if (lstrcmp(FindFileData.cFileName, TEXT(".")) == 0 || lstrcmp(FindFileData.cFileName, TEXT("..")) == 0)
{
continue;
}
*/
//打印文件名,目录名
printf("%s\t\t", FindFileData.cFileName);
//判断文件属性,是否为加密文件或文件夹
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)
{
printf("加密\n");
}
//判断文件属性是否为隐藏文件或文件夹
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
{
printf("隐藏\n");
}
//判断文件属性是否为目录
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
printf("DIR");
//如果是目录,可以继续查找下去
CHAR szNewFilePath[MAX_PATH] = {9};
wsprintf(szNewFilePath, "%s\\%s", szPath, FindFileData.cFileName);
EnumerateFileInDirectory(szNewFilePath);
}
} while (FindNextFile(hListFile, &FindFileData));
}
return 0;
}
/*************************************************************
SaveDataToFile
功能 : 读取文件内容
参数 : LPSTR szFilePath 文件路径
**************************************************************/
DWORD ReadFileContent(LPSTR szFilePath)
{
//文件句柄
HANDLE hFileRead = NULL;
//保持文件大小
LARGE_INTEGER liFileSize;
//成功读取文件数据大小
DWORD dwReadedSize;
//累加计算已经读取数据大小
LONGLONG liTotalRead = 0;
//文件数据缓存
BYTE lpFileDataBuffer[32] = {0};
//打开已有文件,读取内容
hFileRead = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//打开文件是否成功
if (hFileRead == INVALID_HANDLE_VALUE)
{
printf("打开文件失败 : %d\n", GetLastError());
return 0;
}
if (!GetFileSizeEx(hFileRead, &liFileSize))
{
printf("获取文件大小失败 : %d\n", GetLastError());
return 0;
}
else
{
printf("文件大小为 : %d\n", liFileSize.QuadPart);
}
//循环读取文件并打印文件内容
while (1)
{
DWORD i;
if (!ReadFile(hFileRead, lpFileDataBuffer, 32, &dwReadedSize, NULL))
{
printf("读取文件错误 : %d\n", GetLastError());
}
printf("读取了%d 个字节, 文件内容是 : ", dwReadedSize);
for (i = 0; i < dwReadedSize; i++)
{
printf("0x%x", lpFileDataBuffer[i]);
}
printf("\n");
liTotalRead += dwReadedSize;
if (liTotalRead == liFileSize.QuadPart)
{
printf("文件读取结束!\n");
break;
}
}
CloseHandle(hFileRead);
return 1;
}
/*************************************************************
SaveDataToFile
功能 : 将数据存储到文件末尾
参数 : LPSTR szFilePath 文件路径
LPVOID lpData 需存储的数据
DWORD dwDataSize 数据大小(字节)
**************************************************************/
DWORD SavaDataToFile(LPSTR szFilePath, LPVOID lpData, DWORD dwDataSize)
{
//文件句柄
HANDLE hFileWrite = NULL;
//成功写入的数据大小
DWORD dwWriteDataSize = 0;
//打开已经存在的文件,读取内容
hFileWrite = CreateFile(szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFileWrite == INVALID_HANDLE_VALUE)
{
printf("打开文件失败 : %d\n", GetLastError());
return 0;
}
//设置文件指针到文件尾
SetFilePointer(hFileWrite, 0, 0, FILE_END);
//将数据写入文件
if (!WriteFile(hFileWrite, lpData, dwDataSize, &dwWriteDataSize, NULL))
{
printf("写入文件失败 : %d\n", GetLastError());
return 0;
}
else
{
printf("写入文件成功, 写入 %d 个字节!\n", dwWriteDataSize);
}
CloseHandle(hFileWrite);
return 1;
}
//ini文件的测试代码
void TestINIFile()
{
//在当前程序目录下创建一个user_setting.ini文件
HANDLE hFile = NULL;
hFile = CreateFile(".\\user_setting.ini", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (NULL == hFile)
{
printf("文件创建失败!\n");
return;
}
CloseHandle(hFile);
//在user_setting.ini文件中创建一个section,并写入数据
BOOL bRet = FALSE;
bRet = WritePrivateProfileString("Column_Section", "Column_Width", "500", ".\\user_setting.ini");
bRet = WritePrivateProfileString("Column_Section", "Column_Height", "500", ".\\user_setting.ini");
bRet = WritePrivateProfileString("Column_Section", "Column_Angle", "0.0", ".\\user_setting.ini");
bRet = WritePrivateProfileString("Column_Attribute", "Column_Id", "1", ".\\user_setting.ini");
bRet = WritePrivateProfileString("Column_Attribute", "Column_Color", "Red", ".\\user_setting.ini");
bRet = WritePrivateProfileString("Column_Attribute", "Column_Point", "Original", ".\\user_setting.ini");
//从user_setting.ini文件中读取某个section的一个key的字符串
CHAR Column_Width[100] = {0};
DWORD dwRes = 0;
dwRes = GetPrivateProfileString("Column_Section", "Column_Width", "300", Column_Width, 100, ".\\user_setting.ini");
CHAR Column_Height[100] = {0};
dwRes = GetPrivateProfileString("Column_Section", "Column_Width", "300", Column_Height, 100, ".\\user_setting.ini");
CHAR Column_Angle[100] = {0};
dwRes = GetPrivateProfileString("Column_Section", "Column_Width", "300", Column_Angle, 100, ".\\user_setting.ini");
//从ini文件中读取整个section的内容
CHAR Column_Attribute[300] = {0};
dwRes = GetPrivateProfileSection("Column_Attribute", Column_Attribute, 300, ".\\user_setting.ini");
printf("%s\n", Column_Attribute);
//从ini文件中读取section的名称, 如果 ini 中有两个 Section: [sec1] 和 [sec2],则返回的是 'sec1',0,'sec2',0,0
CHAR Section_Name[100] = {0};
dwRes = GetPrivateProfileSectionNames(Section_Name, 100, ".\\user_setting.ini");
printf("%s\n", Section_Name);
//将一个整个section的内容加入到另外指定的section中, Column_Attribute中的内容覆盖了原来Column_Section中的内容
bRet = WritePrivateProfileSection("Column_Section", Column_Attribute, ".\\user_setting.ini");
}
//获取当前目录,获取程序所在的目录,获取模块路径
void TestOnDirectory()
{
//用于储存当前路径
CHAR szCurrentDirectory[MAX_PATH] = {0};
//用于储存模块路径
CHAR szMoudlePath[MAX_PATH] = {0};
//Kernel32文件名与句柄
LPSTR szKernel32 = "kernel32.dll";
HMODULE hKernel32;
//当前路径的长度,也用于判断获取是否成功
DWORD dwCurDirPathLen;
//获取进程的当前目录
dwCurDirPathLen = GetCurrentDirectory(MAX_PATH, szCurrentDirectory);
if (dwCurDirPathLen == 0)
{
return;
}
printf("%s\n", szCurrentDirectory);
//将进程当前的目录设置为 "C:\"
lstrcpy(szCurrentDirectory, "C:\\");
if (!SetCurrentDirectory(szCurrentDirectory))
{
return;
}
//在当前目录下创建子目录“current_dir"
CreateDirectory("current_dir", NULL);
//再次获取系统当前目录
dwCurDirPathLen = GetCurrentDirectory(MAX_PATH, szCurrentDirectory);
if (dwCurDirPathLen == 0)
{
return;
}
printf("GetCurrentDirectory获取的当前目录为 %s\n", szCurrentDirectory);
//使用NULL参数,获取本模块的路径
if (!GetModuleFileName(NULL, szMoudlePath, MAX_PATH))
{
return;
}
printf("本模块路径 %s", szMoudlePath);
//获取Kernel32.dll的模块句柄
hKernel32 = LoadLibrary(szKernel32);
//获取kernel32.dll的模块句柄
if (!GetModuleFileName(hKernel32, szMoudlePath, MAX_PATH))
{
return;
}
printf("kernel32.dll模块路径 %s", szMoudlePath);
return;
}
//对文件的属性进行显示的一些函数
DWORD ShowFileTime(PFILETIME lptime);
DWORD ShowFileSize(DWORD dwFileSizeHigh, DWORD dwFileSizeLow);
DWORD ShowFileAttrInfo(DWORD dwAttribute);
DWORD ShowFileAttribute(LPSTR szPath)
{
WIN32_FILE_ATTRIBUTE_DATA wfad;
printf("文件 : %s\n", szPath);
//获取文件属性
if (!GetFileAttributesEx(szPath, GetFileExInfoStandard, &wfad))
{
return 1;
}
//显示相关信息
printf("创建时间 : \t");
ShowFileTime(&(wfad.ftCreationTime));
printf("最后访问时间 : \t");
ShowFileTime(&(wfad.ftLastAccessTime));
printf("最后修改时间 : \t");
ShowFileTime(&(wfad.ftLastWriteTime));
//显示文件的大小
ShowFileSize(wfad.nFileSizeHigh, wfad.nFileSizeLow);
//显示文件属性
ShowFileAttrInfo(wfad.dwFileAttributes);
return 0;
}
DWORD ShowFileTime(PFILETIME lptime)
{
//文件时间结构
FILETIME ftLocal;
//系统时间结构
SYSTEMTIME st;
//调整为系统所在时区的时间
FileTimeToLocalFileTime(lptime, &ftLocal);
//将文件时间格式转换
FileTimeToSystemTime(&ftLocal, &st);
//显示时间字符
printf("%4d year %2d month %2d day, %#02d:%#02d:%#02d\n", st.wYear, st.wMonth, st.wDay, st.wMinute, st.wSecond);
return 0;
}
DWORD ShowFileSize(DWORD dwFileSizeHigh, DWORD dwFileSizeLow)
{
ULONGLONG liFilesize;
liFilesize = dwFileSizeHigh;
//移动到32位
liFilesize <<= sizeof(DWORD) * 8;
liFilesize += dwFileSizeLow;
printf("文件大小 : \t%I64u字节\n", liFilesize);
return 0;
}
DWORD ShowFileAttrInfo(DWORD dwAttribute)
{
//一次判断文件的属性并显示
printf("文件属性 : \t");
if (dwAttribute & FILE_ATTRIBUTE_ARCHIVE)
{
printf("ARCHIVE\N");
}
if (dwAttribute & FILE_ATTRIBUTE_COMPRESSED)
printf("压缩文件");
if (dwAttribute & FILE_ATTRIBUTE_DIRECTORY)
printf("目录文件");
if (dwAttribute & FILE_ATTRIBUTE_ENCRYPTED)
printf("加密文件");
if (dwAttribute & FILE_ATTRIBUTE_HIDDEN)
printf("隐藏文件");
if (dwAttribute & FILE_ATTRIBUTE_NORMAL)
printf("Normal");
if (dwAttribute & FILE_ATTRIBUTE_OFFLINE)
printf("OFFLINE");
if (dwAttribute & FILE_ATTRIBUTE_READONLY)
printf("只读文件");
if (dwAttribute & FILE_ATTRIBUTE_SPARSE_FILE)
printf("sparse");
if (dwAttribute & FILE_ATTRIBUTE_SYSTEM)
printf("系统文件");
if (dwAttribute & FILE_ATTRIBUTE_TEMPORARY)
printf("临时文件");
printf("\n");
return 0;
}
//给文件添加其他属性
DWORD SetFileHiddenAndReadOnly(LPSTR szFileName)
{
//获取原来的属性
DWORD dwFileAttributes = GetFileAttributes(szFileName);
//添加
dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
//设置文件属性,并判断是否成功
if (SetFileAttributes(szFileName, dwFileAttributes))
{
printf("文件 %s 的隐藏和属性设置成功\n", szFileName);
}
else
{
printf("文件设置失败 %d\n", GetLastError());
}
return 0;
}
//对文件进行复制,删除,移动
int main(int argc, PCHAR argv[])
{
if (0 == lstrcmp("-d", argv[1]) && argc == 3)
{
if (!DeleteFile(argv[2]))
{
printf("删除文件错误!\n");
return 1;
}
else
{
printf("删除文件成功!\n");
}
}
else if (0 == lstrcmp("-c", argv[1]) && argc == 4)//复制文件
{
if (!CopyFile(argv[2], argv[3], TRUE))
{
//lastError == 0X50,文件存在
if (GetLastError() == 0x50)
{
printf("文件已经存在,是否覆盖? Y/N", argv[3]);
if ('y' == getchar())
{
//复制,覆盖已经存在的文件
if (!CopyFile(argv[2], argv[3], FALSE))
{
printf("复制文件错误!\n");
}
else
{
printf("复制成功!\n");
}
}
else
return 0;
}
}
}
else if (0 == lstrcmp("-m", argv[1]) && argc == 4)
{
if (!MoveFile(argv[2], argv[3]))
{
printf("移动文件错误\n");
}
else
{
printf("参数错误!\n");
}
}
return 0;
}