win32 文件

得到当前文件路径

GetCurrentDirectory();

//获取当前进程的当前目录。
DWORD GetCurrentDirectory(DWORD nBufferLength,  //缓冲区的长度
                          LPTSTR lpBuffer);     //指定一个预定义字串,用于保存当前目录

代码演示

TCHAR strArr[1024] = {};
//WndProc消息处理函数中
switch (message)
{
    //鼠标的左键按下
    case WM_LBUTTONDOWN: 
    {
        //得到当前的工作路径
		GetCurrentDirectory(1023,strArr);
        Message(0,strArr,0,0);
    }
        break;
}

得到临时路径

GetTempPath();

临时路径是由TMP环境变量指定的一个路径。如TMP不存在,则是由TEMP环境变量指定的路径。如果这两个环境变量都不存在,就是当前目录。

通过把资源文件解包到临时文件夹,然后在临时文件夹中读取程序所需资源文件,因为win32 GDI不支持从内存地址中获取资源文件。

//获取为临时文件指定的路径
DWORD GetTempPath(DWORD nBufferLength,  //缓冲区的长度
                  LPTSTR lpBuffer);     //指定一个预定义字串,用于保存当前目录

代码演示

//通过把资源文件解包到临时文件夹,然后在临时文件夹中读取程序所需资源文件
TCHAR strArr[1024] = {};
//WndProc消息处理函数中
switch (message)
{
    //鼠标的左键按下
    case WM_LBUTTONDOWN: 
    {
        //得到当前的工作路径
		GetTempPath(1023,strArr);
        Message(0,strArr,0,0);
    }
        break;
}

打开或者创建新文件

CreateFile()//打开或新建文件

//打开或新建文件
HANDLE CreateFile(_In_ LPCTSTR lpFileName,        //要打开的文件的名或设备名
                  _In_ DWORD dwDesiredAccess,      //文件访问权限
                  _In_ DWORD dwShareMode,          //共享权限
                  _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,//定义了文件的安全特性
                  _In_ DWORD dwCreationDisposition,//文件打开或者创建方式
                  _In_ DWORD dwFlagsAndAttributes, //文件属性
                  _In_opt_ HANDLE hTemplateFile);  //文件模板属性

参数说明

lpFileName String要打开的文件的名或设备名。这个字符串的最大长度在ANSI版本中为MAX_PATH,在unicode版本中为32767。

dwDesiredAccess指定类型的访问对象。如果为 GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);如果为零,表示只允许获取与一个设备有关的信息 。

另外,还可以指定下面的控制标志:

标准控制权限(16-23位掩码):

描述
DELETE删除对象的权限。
READ_CONTROL从对象的安全描述符中读取信息的权限,但不包括SACL(系统访问控制列表)中的信息。
WRITE_DAC修改对象安全描述符中的DACL(随机访问控制列表)的权限
WRITE_OWNER修改对象安全描述符中的属主的权限
SYNCHRONIZE同步化使用对象的权限,即可以创建一个线程等待信号量释放(但有些对象不支持这个权限)。
STANDARD_RIGHTS_REQUIRED等价于前面四种权限的总合(通常这四种是必须具有的权限)。
STANDARD_RIGHTS_READ一般等价于READ_CONTROL
STANDARD_RIGHTS_WRITE一般等价于READ_CONTROL
STANDARD_RIGHTS_EXECUTE一般等价于READ_CONTROL
STANDARD_RIGHTS_ALL等价于前面五种权限的总合。

特殊控制权限(0-15位掩码):

描述
SPECIFIC_RIGHTS_ALL
ACCESS_SYSTEM_SECURITY
MAXIMUM_ALLOWED
GENERIC_READ文件只读
GENERIC_WRITE文件只写
GENERIC_EXECUTE文件一直存在用此属性
GENERIC_ALL文件可读写

注:实质上是通过ACCESS_MASK结构体的一个双字值来设置标准权限、特殊权限和一般权限的。

dwShareModeLong, 文件共享属性,值如下:

描述
0如果是零表示不共享;
FILE_SHARE_DELETE表示随后打开操作对象会成功,但只有删除访问请求的权限;
FILE_SHARE_READ随后打开操作对象会成功只有请求读访问的权限;
FILE_SHARE_WRITE随后打开操作对象会成功,但只有请求写访问的权限。

lpSecurityAttributesSECURITY_ATTRIBUTES, 指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性(如果操作系统支持的话),一般赋值为NULL;

dwCreationDispositionLong,下述常数之一:

描述
CREATE_NEW创建文件;如文件存在则会出错
CREATE_ALWAYS创建文件,会改写前一个文件
OPEN_EXISTING文件必须已经存在。由设备提出要求
OPEN_ALWAYS如文件不存在则创建它
TRUNCATE_EXISTING将现有文件缩短为零长度

dwFlagsAndAttributesLong, 一个或多个下述常数

描述
FILE_ATTRIBUTE_ARCHIVE标记归档属性
FILE_ATTRIBUTE_COMPRESSED将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
FILE_ATTRIBUTE_NORMAL默认属性
FILE_ATTRIBUTE_HIDDEN隐藏文件或目录
FILE_ATTRIBUTE_READONLY文件为只读
FILE_ATTRIBUTE_SYSTEM文件为系统文件
FILE_FLAG_WRITE_THROUGH操作系统不得推迟对文件的写操作
FILE_FLAG_OVERLAPPED允许对文件进行重叠操作
FILE_FLAG_NO_BUFFERING禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
FILE_FLAG_RANDOM_ACCESS针对随机访问对文件缓冲进行优化
FILE_FLAG_SEQUENTIAL_SCAN针对连续访问对文件缓冲进行优化
FILE_FLAG_DELETE_ON_CLOSE关闭了上一次打开的句柄后,将文件删除。特别适合临时文件

也可在Windows NT下组合使用下述常数标记:

SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY

hTemplateFile,hTemplateFile为一个文件或设备句柄,表示按这个参数给出的句柄为模板创建文件(就是将该句柄文件拷贝到lpFileName指定的路径,然后再打开)。它将指定该文件的属性扩展到新创建的文件上面,这个参数可用于将某个新文件的属性设置成与现有文件一样,并且这样会忽略dwAttrsAndFlags。通常这个参数设置为NULL,为空表示不使用模板,一般为空。


文件读写

文件读写不能用宽字节,如果用了宽字节,需要自己做转换。

WriteFile() 写文件

//写文件
BOOL WriteFile(HANDLE  hFile,   //文件句柄
               LPCVOID lpBuffer,//数据缓存区指针
               DWORD   nNumberOfBytesToWrite,//你要写的字节数
               LPDWORD lpNumberOfBytesWritten,//用于保存实际写入字节数的存储区域的指针
               LPOVERLAPPED lpOverlapped//OVERLAPPED结构体指针);

从文件指针指向的位置开始将数据写入到一个文件中, 且支持同步和异步操作,

如果文件打开方式没有指明FILE_FLAG_OVERLAPPED的话,当程序调用成功时,它将实际写入文件的字节数保存到lpNumberOfBytesWriten指明的地址空间中。

如果文件要交互使用的话,当函数调用完毕时要记得调整文件指针。

参数说明

HANDLE hFile, 需要写入数据的文件指针,这个指针指向的文件必须是GENERIC_WRITE access 访问属性的文件

LPOVERLAPPED lpOverlapped OVERLAPPED结构体指针,如果文件是以FILE_FLAG_OVERLAPPED方式打开的话,那么这个指针就不能为NULL

vc返回值

调用成功,返回非0

调用不成功,返回为0

ReadFile() 读文件

//读取文件
BOOL ReadFile(HANDLE hFile,//文件的句柄
              LPVOID lpBuffer,//用于保存读入数据的一个缓冲区
              DWORD nNumberOfBytesToRead,//要读入的字节数
              LPDWORD lpNumberOfBytesRead,//指向实际读取字节数的指针
              LPOVERLAPPED lpOverlapped);//如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。//该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
/*FILE_FLAG_OVERLAPPED
文件或设备被打开或创建异步I / O。
当后续的I / O操作完成这个句柄,OVERLAPPED结构中指定的事件 将被设置为有信号状态。
如果这个标志被指定,该文件可用于同时读取和写入操作。
如果没有指定这个标志,然后被序列化I / O操作,即使调用读写函数指定一个OVERLAPPED结构。*/

参数说明

HANDLE hFile, 需要读入数据的文件指针,这个指针指向的文件必须是GENERIC_READ 访问属性的文件。

LPVOID lpBuffer,接收数据的缓冲区。

DWORD nNumberOfBytesToRead,指定要读取的字节数。

LPDWORD lpNumberOfBytesRead,指向一个DWORD类型变量的指针,用来接收读取的字节数。如果下一个参数为NULL,那么一定要传入这个参数。

LPOVERLAPPED lpOverlapped OVERLAPPED结构体指针,如果文件是以FILE_FLAG_OVERLAPPED方式打开的话,那么这个指针就不能为NULL。

FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作

调用成功,返回非0

调用不成功,返回为0

会设置GetLastError。如启动的是一次异步读操作,则函数会返回零值,并将ERROR_IO_PENDING设置成GetLastError的结果。如结果不是零值,但读入的字节数小于nNumberOfBytesToRead参数指定的值,表明早已抵达了文件的结尾。


设置文件中的读取位置

SetFilePointer() 在一个文件中设置新的读取位置。

DWORD SetFilePointer(HANDLE hFile,              //文件句柄
                     LONG lDistanceToMove,      //偏移量(低位)
                     PLONG lpDistanceToMoveHigh,//偏移量(高位)
                     DWORD dwMoveMethod);       //基准位置 

参数 类型及说明

hFile系统文件句柄

lDistanceToMove Long,字节偏移量

lpDistanceToMoveHigh Long,指定一个长整数变量,其中包含了要使用的一个高双字偏移。可设为零(将声明变为ByVal),表示只使用lDistanceToMove

dwMoveMethod Long,下述值之一

描述
FILE_BEGIN将新位置设为从文件起始处开始算的起的一个偏移
FILE_CURRENT将新位置设为从当前位置开始计算的一个偏移
FILE_END将新位置设为从文件尾开始计算的一个偏移

关闭文件句柄

CloseHandle() 关闭文件句柄

CloseHandle包括文件、文件映射、进程、线程、安全和同步对象等。涉及文件处理时,这个函数通常与vb的close命令相似。应尽可能的使用close,因为它支持vb的差错控制。

//关闭一个内核对象
BOOL CloseHandle(HANDLE hObject); //Object代表一个已打开对象handle。

返回值

TRUE:执行成功;

FALSE:执行失败,可以调用GetLastError()获知失败原因。

关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。

若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。


win32 实现文件操作

方法如下

  1. 定义用于文件操作的句柄
  2. 创建文件
  3. 读或者写文件
  4. 关闭文件句柄

代码演示

TCHAR strArr[1024] = {};
//WndProc消息处理函数中
switch (message)
{
    //鼠标的左键按下
    case WM_LBUTTONDOWN: 
    {
        //1.定义用于文件操作的句柄
		HANDLE hFile = nullptr;
        //2.创建文件
        hFile = CreateFile(_T"1.txt",            //路径的文件名,用相对路径
                           GENERIC_ALL,          //文件访问权限,可读写
                           FILE_SHARE_READ,      //共享只读读模式
                           nullptr;              //安全属性
                           OPEN_ALWAYS;          //文件创建方式
                           FILE_ATTRIBUTE_NORMAL,//文件属性
                           nullptr);             //文件模板属性
        //3.读或者写文件
        char strp[1024] = "hello world 老师好";
        DWORD len = 0;
        //读文件
        ReadFile(hFile,strp,1023,&len,nullptr);
        //写文件
        WriteFile(hFile,      //操作文件的句柄
                 strp,        //写入的内容
                 strlen(strp),//想写入的字符个数
                 &len,        //写入的具体个数(输出)
                 nullptr);
        Message(0,strArr,0,0);
        //设置文件内部指针的偏移
        SetFilePointer(hFile,      //操作文件的句柄
                      0,           //低32位偏移量
                      0,           //高32位偏移量
                      FILE_BEGIN); //从文件的起始位置进行偏移
        //4.关闭文件句柄
        CloseHandle(hFile);
    }
        break;
}

文件的目录操作

FindFirstFile()

根据文件名查找文件

该函数到一个文件夹(包括子文件夹)去搜索指定文件 如果要使用附加属性去搜索文件的话 可以使用FindFirstFileEx函数。

//根据文件名查找文件
HANDLE FindFirstFile(LPCTSTR lpFileName,   //lpFileName文件名(包括路径)
                     LPWIN32_FIND_DATA lpFindFileData);//指向一个用于保存文件信息的结构体

参数 类型及说明

lpFileName,String;类型欲搜索的文件名。参数可如下

"c:/Windows/*.*"           //在c:\Windows目录中查找所有件
"c:/Windows/System32/*.dll"//在c:\Windows\System32目录中查找所有dll文件
"c:/Windows/System.ini"    //在c:\Windows目录中查找System.ini文件
"c:/Windows/a???.*"        //在c:\Windows目录中查找所有以a开头的文件名长度.为4个字符的文件
"Test.dat"                 //在当前目录查找Test.dat文件
"*.*"                      //在当前目录查找所有文件

(注!一定要带文件名。如果参数为“c:\Windows”,则返回的文件名为“Windows”,并且接下来调用FindNextFile会返回失败)

lpFindFileData WIN32_FIND_DATA类型结构体,这个结构用于装载与找到的文件有关的信息。该结构可用于后续的搜索

typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes;               // 文件属性
FILETIME ftCreationTime;              // 文件创建时间
FILETIME ftLastAccessTime;            // 文件最后一次访问时间
FILETIME ftLastWriteTime;             // 文件最后一次修改时间
DWORD nFileSizeHigh;                  // 文件长度高32位
DWORD nFileSizeLow;                   // 文件长度低32位
DWORD dwReserved0;                    // 系统保留
DWORD dwReserved1;                    // 系统保留
TCHAR cFileName[MAX_PATH];            // 长文件名
TCHAR cAlternateFileName[14];         // 8.3格式文件名
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

其中 dwFileAttributes字段可以是下面取值的组合,通过这个字段可以检查找到的究竟是一个文件还是一个子目录,以及其他的文件属性:

描述
FILE_ATTRIBUTE_ARCHIVE文件包含归档属性
FILE_ATTRIBUTE_COMPRESSED文件和目录被压缩
FILE_ATTRIBUTE_DIRECTORY找到的是一个目录
FILE_ATTRIBUTE_HIDDEN文件包含隐含属性
FILE_ATTRIBUTE_NORMAL文件没有其他属性
FILE_ATTRIBUTE_READONLY文件包含只读属性
FILE_ATTRIBUTE_SYSTEM文件包含系统属性
FILE_ATTRIBUTE_TEMPORARY文件是一个临时文件

返回的文件名中会包含".“和”…"。“.'代表本目录,"…"代表上一层目录。一般情况下需要把这两个名称过滤掉。比如要进行文件删除操作。

由这个函数返回的句柄可以作为一个参数用于FindNextFile函数。这样一来,就可以方便的枚举出与lpFileName参数指定的文件名相符的所有文件

FindNextFile()

可以用来遍历目录或文件时,判断当前目录下是否有下一个目录或文件。

//遍历目录或文件时,判断当前目录下是否有下一个目录或文件。
BOOL FindNextFile(HANDLE hFindFile,                //上一次查找返回的文件句柄
                 LPWIN32_FIND_DATA lpFindFileData);// WIN32_FIND_DATA结构体,这个结构用于装载与找到的文件有关的信息。该结构可用于后续的搜索

此函数用于遍历目录或文件时,判断当前目录下是否有下一个目录或文件

Long,如执行成功,返回TRUE。否则为FALSE。

WIN32_FIND_DATA结构体详见上面的说明。

代码演示

TCHAR strArr[1024] = {};
//WndProc消息处理函数中
switch (message)
{
    //鼠标的左键按下
    case WM_LBUTTONDOWN: 
    {
        //准备一个辅助数组
        char fileStr[1024] = {};
        //1.定义用于文件操作的句柄
		HANDLE hFile = nullptr;
        //2.创建文件
        hFile = CreateFile(_T"2.txt",            //路径的文件名,用相对路径
                           GENERIC_WRITE,        //文件访问权限,只写
                           FILE_SHARE_READ,      //共享只读读模式
                           nullptr;              //安全属性
                           CREATE_ALWAYS;        //文件创建方式
                           FILE_ATTRIBUTE_NORMAL,//文件属性
                           nullptr);             //文件模板属性
        //文件的数据结构
        WIN32_FIND_DATAA fileData;
        //查找第一个文件
        HANDLE findFile = nullptr;
        findFile = FindFirstFileA('Debug/*.*', //路径文件名,表示找Debug下的所有文件
                     &fileData);//文件数据结构
        
//情空保存文件名的辅助数组
        memcpy(fileStr,fileData.cFileName,sizeof(char)*strlen(fileData.cFileName));
        //文件名尾部拼接\r\n  表示换行
        strcat(fileStr,"\r\n");
        DWORD len = 0;
        //把找到的文件名写入2.txt文件中
        WriteFile(hFile,fileStr,strlen(fileStr),$len,nullptr);
        //继续查找下一个文件
        while(FindNextFileA(findFile,&fileData))
        {
            ZeroMemory(fileStr,sizeof(char)*1024);
            memcpy(fileStr,fileData.cFileName,sizeof(char)*strlen(fileData.cFileName));
            strcat(fileStr,"\r\n");
            WriteFile(hFile,fileStr,strlen(fileStr),$len,nullptr);
        }
        //4.关闭文件句柄
        CloseHandle(findFile);
        CloseHandle(hFile);
    }
        break;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值