当前位置: 首页 > article >正文

Window系统编程 - 文件操作

前言

  • 各位师傅大家好,我是qmx_07,今天主要介绍使用windows系统编程操作读写文件
    在这里插入图片描述

文件

CreateFile()函数讲解

  • 介绍:该函数用于打开文件或者I/O流设备,文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和管道

  • 接下来我们学习一下CreateFile这个函数,需要对各参数有一定了解
    函数原型:

HANDLE CreateFileA(
  [in]           LPCSTR                lpFileName, //要打开的文件名称
  [in]           DWORD                 dwDesiredAccess,//对文件的访问权限,比如读写
  [in]           DWORD                 dwShareMode,//文件的共享权限
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指针
  [in]           DWORD                 dwCreationDisposition,//对已经存在的文件,或不存在的文件 进行什么操作
  [in]           DWORD                 dwFlagsAndAttributes,//文件或设备属性标志
  [in, optional] HANDLE                hTemplateFile//模版文件
);

简单了解参数含义,接下来进行详细讲解
这边的A 版本代表Ascii环境,W代表 Unicode环境,EX代表拓展版本函数

lpFileName
  • 要创建的文件或者设备名称,假如我要在D盘创建hello.txt,该参数内容如下:
D:\\hello.txt
  • 一般会将该参数限制到MAX_PATH字符为260
    在这里插入图片描述
dwDesiredAccess
  • 对文件或者设备的访问权限
    在这里插入图片描述
  • 常见的全部权限、可读、可写、可执行
dwShareMode
  • 文件或者设备的共享模式,如果为NULL,则不允许共享访问
    在这里插入图片描述
lpSecurityAttributes
  • 该参数主要用作继承
  • 文件操作:文件的访问权限和句柄的继承属性
  • 进程创建:继承父进程的资源访问
dwCreationDisposition
  • 对于已经存在的文件,或不存在的文件,做出操作
    在这里插入图片描述
    在这里插入图片描述
  • 以上是对文件的两种状况,及作用总结
dwFlagsAndAttributes
  • 设置文件的属性或标志
    在这里插入图片描述
  • 这几个文件属性比较常用
hTemplateFile
  • GENERIC_READ 访问权限的模板文件的有效句柄

写文件

	HANDLE hFile = CreateFile("G:\\qmx.ini", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		std::cout << "CreateFile Faild" << std::endl;
		std::cout << GetLastError() << std::endl;
	}
	CHAR * Buffer[MAX_PATH] = { 0 };
	CHAR arr[20] = "hello world!";
	DWORD length = strlen(arr);
	memcpy(Buffer, arr, length);

	DWORD NumerOfBytesWritten = 0;
	BOOL Ret = WriteFile(hFile, Buffer, length, &NumerOfBytesWritten, NULL);
	if (!Ret)
	{
		std::cout << "WriteFile Faild" << std::endl;
		std::cout << GetLastError() << std::endl;
	}
	CloseHandle(hFile);
  • 通过CreateFile创建文件句柄(具有读写权限的普通文件打开)
  • 将向写入的数据写入Buffer,利用WriteFile()写入文件
  • CloseHandle() 关闭句柄
    在这里插入图片描述
    文件被成功写入
WriteFile()

函数原型:

BOOL WriteFile(
  [in]                HANDLE       hFile, //文件或设备句柄
  [in]                LPCVOID      lpBuffer,//缓冲区
  [in]                DWORD        nNumberOfBytesToWrite,//写入字符的长度
  [out, optional]     LPDWORD      lpNumberOfBytesWritten,//实际写入字符的长度
  [in, out, optional] LPOVERLAPPED lpOverlapped//表示异步I/O操作
);

在这里插入图片描述

  • 创建变量NumerOfBytesWritten,用于存储实际写入的长度,NULL 表示进行同步写入操作
  • WriteFile返回值,如果函数写入失败返回False,写入成功返回True
错误码调试

在这里插入图片描述

  • 将前面写好的文件,改为 CREATE_NEW,使用GetLastError()捕获错误码
    在这里插入图片描述
  • 在工具中的错误查找,查询错误码,能够快速了解到哪里有问题

在这里插入图片描述

  • INVALID_HANDLE_VALUE 代表句柄失效

读取文件

	HANDLE hFile = CreateFile("G:\\qmx.ini", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		std::cout << "CreateFile Faild" << std::endl;
		std::cout << GetLastError() << std::endl;
	}
	LARGE_INTEGER FileSize;
	if (!GetFileSizeEx(hFile, &FileSize))
	{
		std::cout << "GetFileSizeEx Failed" << std::endl;
		std::cout << GetLastError() << std::endl;
	}
	CHAR* Buffer = new CHAR[FileSize.LowPart + 1];
	memset(Buffer, 0, FileSize.LowPart + 1);
	DWORD NumberOfBytesRead = 0;
	BOOL Ret = ReadFile(hFile, Buffer, FileSize.LowPart, &NumberOfBytesRead, NULL);
	if (!Ret)
	{
		std::cout << "ReadFile Faild" << std::endl;
		std::cout << GetLastError() << std::endl;
	}
	std::cout << Buffer << std::endl;
	CloseHandle(hFile);
  • 通过CreateFile创建文件句柄(具有读写权限的普通文件打开)
  • 创建LARGE_INTEGER类型的变量用于存储文件大小,通过GetFileSizeEx判断能否存储
  • 使用ReadFile将文件数据存储到Buffer,并输出
    在这里插入图片描述
ReadFile

在这里插入图片描述

  • LARGE_INTEGER类型原型:
    在这里插入图片描述
  • LowPart存储着32位无符号整型,如果溢出则使用HighPart
BOOL ReadFile(
  [in]                HANDLE       hFile,//文件或设备句柄
  [out]               LPVOID       lpBuffer,//缓冲区
  [in]                DWORD        nNumberOfBytesToRead,//读取长度
  [out, optional]     LPDWORD      lpNumberOfBytesRead,//实际读取的长度
  [in, out, optional] LPOVERLAPPED lpOverlapped//表示异步I/O操作
);

在这里插入图片描述

  • 读取文件内容,通过FileSize.LowPart 获取文件读取长度,写入Buffer
  • ReadFile返回值,如果函数写入失败返回False,写入成功返回True
文件随机读写
  • 不从开头开始读取,需要使用setFilePointer函数
    原型:
DWORD SetFilePointer(
  [in]                HANDLE hFile,//文件句柄
  [in]                LONG   lDistanceToMove,//移动的步长
  [in, out, optional] PLONG  lpDistanceToMoveHigh,//高32位
  [in]                DWORD  dwMoveMethod//文件指针的位置
);

在这里插入图片描述
在这里插入图片描述

  • 通过setFilePointer函数移动两位步长

文件操作

移动文件

MoveFile(源文件,目标文件),用于移动文件位置
在这里插入图片描述

  • 原理:通过读取文件内容,写入新文件,再将源文件删除
删除文件

在这里插入图片描述

  • 通过DeleteFile(源文件)删除文件
复制文件
  • CopyFile(源文件,目标文件,True) 用于复制文件
    在这里插入图片描述
    在这里插入图片描述

总结

  • 介绍了CreateFile()、WriteFile()、ReadFile()参数详解,以及读写文件的函数使用,怎么利用错误码调试

http://www.kler.cn/news/340799.html

相关文章:

  • 国庆档不太热,影视股“凉”了?
  • Win10之Ubuntu22.04(主机)与Virtual-BOX(宿主win10)网络互通调试(七十九)
  • k8s 中存储之 PV 持久卷 与 PVC 持久卷申请
  • 实现std::sort,replace,fill,accumulate,equal等函数
  • MyBatis之TypeHandler的自定义实现
  • Golang | Leetcode Golang题解之第462题最小操作次数使数组元素相等II
  • GNU/Linux - tarball文件介绍介绍
  • C#中Json序列化的进阶用法
  • Spring中注入bean时的scope属性详解、往singleton中注入prototype属性的bean以及Spring使用注解实现AOP切面编程
  • qwt实现码流柱状图多色柱体显示
  • SAP将假脱机(Spool requests)内容转换为PDF文档[RSTXPDFT4]
  • GAMES202作业3
  • 27-云计算下一个十年技术Serverless
  • 阿里140滑块-滑块验证码逆向分析思路学习
  • class 031 位运算的骚操作
  • Spring Boot 整合 Minio
  • JavaScript基础---typeof和instanceof的区别
  • git 相关问题解决一一记录
  • 斯坦福 CS229 I 机器学习 I 构建大型语言模型 (LLMs)
  • 如何在两台服务器之间迁移 MySQL 数据库