win32api之文件系统管理(七)

什么是文件系统

文件系统是一种用于管理计算机存储设备上文件和目录的机制。文件系统为文件和目录分配磁盘空间,管理文件和目录的存储和检索,以及提供对它们的访问和共享,以下是常见的两种文件系统:

NTFSFAT32
磁盘分区容量2T32G
单个文件容量4G以上最大4G
EFS加密支持不支持
磁盘配额支持不支持

什么是卷

卷是操作系统对磁盘分区的逻辑抽象,可以看作是磁盘分区的容器。在一个物理磁盘中可以分为多个卷,每个卷可以分配不同的文件系统,从而实现对数据的管理和存储

每个卷都有一个唯一的卷标识符,可以通过这个标识符来访问和管理它的数据


卷相关API

GetLogicalDrives

GetLogicalDrivers函数用于获取当前系统中存在卷的数量,其返回值为一个32位无符号整数,每个比特位表示一个卷的状态。若比特位为1,则代表对应的卷存在,其语法格式如下:

DWORD GetLogicalDrives(void);

以下是常见的返回值以及对应的含义:

  • 返回值为0x01(二进制为0001):表示只有A盘存在
  • 返回值为0x02(二进制为0010):表示只有B盘存在;
  • 返回值为0x03(二进制为0011):表示A盘和B盘都存在;
  • 返回值为0x04(二进制为0100):表示只有C盘存在;
  • 返回值为0x0C(二进制为1100):表示只有C盘和D盘存在
  • 返回值为0X0F(二进制为1111):表示ABCD盘都存在

GetLogicalDriveStrings

GetLogicalDriveStrings函数用于获取系统上所有逻辑驱动器的名称和根目录,换句话说就是获取卷的标识符,函数调用成功后,函数返回值为返回的字符数组中的字符数,若函数失败,则返回值为0

其语法格式如下:

DWORD GetLogicalDriveStrings(
  DWORD  nBufferLength,  //存储驱动器名称的缓冲区的大小
  LPTSTR lpBuffer //指向缓冲区的指针
);

GetDriveType

GetDriveType函数用于获取指定驱动器的类型

UINT GetDriveType(
  LPCWSTR lpRootPathName  //要获取其驱动器类型的根目录路径
);

其返回值是一个整数,代表驱动器的类型,取值如下:

  • DRIVE_UNKNOWN(0):未知类型的驱动器。

  • DRIVE_NO_ROOT_DIR(1):驱动器不存在或根路径无效。

  • DRIVE_REMOVABLE(2):可移动磁盘。

  • DRIVE_FIXED(3):固定磁盘。

  • DRIVE_REMOTE(4):网络驱动器。

  • DRIVE_CDROM(5):光盘驱动器。

  • DRIVE_RAMDISK(6):RAM磁盘。

GetVolumeInformation

GetVolumeInformation函数用于获取卷的相关信息(如卷名称、文件系统、卷序列号等)。如果函数执行成功,则返回值为TRUE;如果执行失败,则返回值为FALSE

其语法格式如下:

BOOL GetVolumeInformation(
  LPCWSTR lpRootPathName,  // IN 指定驱动器的根路径
  LPWSTR  lpVolumeNameBuffer,  // OUT 接收卷名称的缓冲区
  DWORD   nVolumeNameSize,  // IN 缓冲区大小(以字符数为单位)
  LPDWORD lpVolumeSerialNumber,  // OUT 接收卷序列号的指针
  LPDWORD lpMaximumComponentLength,  // OUT 接收最大文件名称长度的指针
  LPDWORD lpFileSystemFlags,  // OUT 接收文件系统标识的指针
  LPWSTR  lpFileSystemNameBuffer,  // OUT 接收文件系统名称的缓冲区
  DWORD   nFileSystemNameSize  // IN文件系统名称缓冲区大小
);

使用实例

include <windows.h>
include <bitset>

int main()
{	
	//获取卷的数量
	DWORD dwLogicalDrivers = GetLogicalDrives();

	//将十进制转换成二进制并输出
	std::bitset<8> bits(dwLogicalDrivers);
	std::cout <<"卷的状态是:"<< bits.to_string()<<std::endl;
	
	// 遍历所有卷的标识符
	TCHAR szBuffer[100];
	GetLogicalDriveStrings(20, szBuffer);
	std::cout << "卷的标识符有:";
	for (TCHAR* drive = szBuffer; *drive != '\0'; drive += lstrlen(drive) + 1) {
        std::cout << drive << ",";
    }
	std::cout<<std::endl;

	
	//获取卷的类型
	UINT DriveType = GetDriveType("D:\\");
	printf("卷的类型是:%u\n", DriveType);
	

	//获取卷的信息
	TCHAR VolumeName[200] = { 0 };
	DWORD VolumeSerial = 0;
	DWORD MaxLength = 0;
	DWORD FileSystemIDC = 0;
	TCHAR FileSystemName[200] = { 0 };
	GetVolumeInformation(
		"E:\\",  
		VolumeName,  
		200,
		&VolumeSerial,
		&MaxLength,
		&FileSystemIDC,
		FileSystemName,
		200
	);
	printf("卷名=%s\n序列号=%d\n文件系统标识=%d\n文件系统名称=%s", VolumeName, VolumeSerial,FileSystemIDC,FileSystemName);
		
}	

执行结果如下:

image-20230303165233294


目录相关API

CreateDirectory

CreateDirectory函数用于创建一个新目录,其语法格式如下:

BOOL CreateDirectory(
  LPCTSTR lpPathName,  //要创建的目录的名称和路径,可以是绝对路径或相对路径
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  //指定了新目录的安全性和访问控制
);

RemoveDirectory

RemoveDirectory函数用于删除指定目录及其所有内容

BOOL RemoveDirectory(
  LPCTSTR lpPathName  //要删除的目录路径
);

MoveFile

MoveFile函数用于将一个文件或目录移动到新的位置,其语法格式如下:

BOOL MoveFile(
  LPCWSTR lpExistingFileName,  //要移动的文件或目录的名称
  LPCWSTR lpNewFileName  //移动后的新位置的路径和名称
);


GetCurrentDirectory

GetCurrentDirectory函数用于获取当前进程的工作目录。其函数原型为

DWORD GetCurrentDirectory(
  DWORD  nBufferLength,  // 缓冲区大小,单位为字节
  LPTSTR lpBuffer        // 存储路径的缓冲区
);

SetCurrentDirectory

SetCurrentDirectory函数用于设置当前进程的工作目录,其语法格式如下:

BOOL SetCurrentDirectory(
  LPCWSTR lpPathName //新的进程工作目录
);

文件相关API

CreateFile

CreateFile函数是一个用于创建或打开文件, 它可以用于创建、读取、写入、修改文件, 函数返回一个文件的句柄, 若执行失败则返回无效句柄值,其语法格式如下:

HANDLE CreateFile(
  LPCTSTR lpFileName,  //创建的文件名
  DWORD dwDesiredAccess,  //文件访问模式
  DWORD dwShareMode,  //共享模式
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,  //安全描述符
  DWORD dwCreationDisposition,  //文件的创建方式
  DWORD dwFlagsAndAttributes,  //文件的属性和标志
  HANDLE hTemplateFile  //指定要用作新文件的属性模板的句柄
);

dwDesiredAccess参数用于指定文件的访问方式, 如下是常见的dwDesiredAccess值:

  • GENERIC_READ:读取文件
  • GENERIC_WRITE:写入文件
  • GENERIC_EXECUTE:执行文件
  • GENERIC_ALL:允许读、写和删除文件

若要指定多个访问方式,可使用OR连接起来,如GENERIC_READ | GENERIC_WRITE


dwShareMode参数指定了其他进程是否可以访问已经打开的文件或设备,如下是常见的值:

  • FILE_SHARE_READ:允许其他进程读取文件或设备。
  • FILE_SHARE_WRITE:允许其他进程写入文件或设备。
  • FILE_SHARE_DELETE:允许其他进程删除文件或设备。

默认情况下,dwShareMode的值为0,即文件或设备不能被共享访问


dwCreationDisposition 参数用于指定创建或打开文件的方式,以下是可取的值:

  • CREATE_NEW:如果文件不存在,则创建文件;否则,打开失败。
  • CREATE_ALWAYS:如果文件不存在,则创建文件。若文件存在,则覆盖该文件
  • OPEN_EXISTING:打开现有文件。如果文件不存在,则打开失败,并返回错误 ERROR_FILE_NOT_FOUND
  • OPEN_ALWAYS:如果文件存在,则打开文件;否则,创建文件。
  • TRUNCATE_EXISTING:打开现有文件,并将其长度截断为零。如果文件不存在,则打开失败,并返回错误 ERROR_FILE_NOT_FOUND

dwFlagsAndAttributes参数是一个标志位,它用于指定创建或打开文件时的一些特殊选项,以下是常见的值

  • FILE_ATTRIBUTE_ARCHIVE:文件存档属性。如果应用程序修改了存档文件,则操作系统会自动清除此属性。
  • FILE_ATTRIBUTE_HIDDEN:隐藏文件或目录。
  • FILE_ATTRIBUTE_NORMAL:标准文件属性。此属性没有任何其他属性设置。
  • FILE_ATTRIBUTE_READONLY:只读文件或目录。如果应用程序尝试修改只读文件,则会导致失败。
  • FILE_ATTRIBUTE_DIRECTORY:指示文件是目录。

GetFileSize

GetFileSize函数用于获取文件的大小,其语法格式如下:

DWORD WINAPI GetFileSize(
  HANDLE  hFile,  //文件句柄
  LPDWORD lpFileSizeHigh  //接收文件大小的指针变量
);		

GetFileAttributeEx

GetFileAttributeEx函数用于获取指定文件或目录的属性信息,其语法格式如下:

BOOL GetFileAttributesEx(
  LPCWSTR            lpFileName,  //要获取属性的文件或目录名
  GET_FILEEX_INFO_LEVELS fInfoLevelId,  //指定文件信息的级别,一般设为GetFileExInfoStandard
  LPVOID             lpFileInformation  //接收文件属性信息的缓冲区指针
);

以下是此函数的使用实例:

include <windows.h>
include <iostream>

int main() {
    WIN32_FILE_ATTRIBUTE_DATA fileData;  // 创建WIN32_FILE_ATTRIBUTE_DATA结构体变量fileData
    if (GetFileAttributesEx(L"C:\\Windows", GetFileExInfoStandard, &fileData)) {  // 获取"C:\\Windows"目录的文件属性,并将属性信息保存在fileData中
        std::cout << "SizeHigh: " << fileData.nFileSizeHigh << std::endl;  // 输出文件大小的高32位
        std::cout << "SizeLow: " << fileData.nFileSizeLow << std::endl;  // 输出文件大小的低32位
        std::cout << "FileAttributes: " << fileData.dwFileAttributes << std::endl;  // 输出文件属性
        std::cout << "CreationTime: " << fileData.ftCreationTime.dwLowDateTime << std::endl;  // 输出创建时间的低32位
        std::cout << "LastAccessTime: " << fileData.ftLastAccessTime.dwLowDateTime << std::endl;  // 输出最后访问时间的低32位
        std::cout << "LastWriteTime: " << fileData.ftLastWriteTime.dwLowDateTime << std::endl;  // 输出最后修改时间的低32位
    }
    return 0;
}

SetFilePointer

SetFilePointer函数用于设置文件指针的位置, 如果函数执行成功,则返回文件指针的新位置, 它的语法如下:

DWORD SetFilePointer(
  HANDLE hFile,        // 文件句柄
  LONG lDistanceToMove, // 文件指针移动的距离,可以为正或负,负数表示向前移动,正数表示向后移动
  PLONG lpDistanceToMoveHigh, // 文件指针移动的高位,常置为NULL
  DWORD dwMoveMethod   // 文件指针的起始位置
);

dwMoveMethod参数表示文件指针的起始位置, 以下是常见值:

  • FILE_BEGIN:文件开头。
  • FILE_CURRENT:文件指针当前位置。
  • FILE_END:文件结尾。

ReadFile

ReadFile函数用于从文件中读取数据, 果读取成功,则函数返回TRUE,否则返回FALSE

它的语法格式如下:

BOOL ReadFile(
  HANDLE       hFile,  //要读取的文件的句柄
  LPVOID       lpBuffer,  //指向缓冲区的指针,用于存储从文件中读取的数据
  DWORD        nNumberOfBytesToRead,  //要读取的字节数
  LPDWORD      lpNumberOfBytesRead,  //指向一个变量的指针,用于接收实际读取的字节数数
  LPOVERLAPPED lpOverlapped  //指向OVERLAPPED结构体的指针,用于支持异步I/O操作,可以传递NULL以进行同步操作
);

WriteFile

WriteFile函数用于将数据写入到文件,其语法格式如下:

BOOL WriteFile(
  HANDLE       hFile,  //文件句柄
  LPCVOID      lpBuffer,  //指向待写入数据的缓冲区指针
  DWORD        nNumberOfBytesToWrite,  //待写入数据的字节数
  LPDWORD      lpNumberOfBytesWritten,  //用于接收实际写入的字节数的指针
  LPOVERLAPPED lpOverlapped
);

CopyFile

CopyFile函数用于将一个文件复制到另一个位置,其语法格式如下:

BOOL CopyFile(
  LPCWSTR lpExistingFileName, // 源文件名
  LPCWSTR lpNewFileName,      // 目标文件名
  BOOL    bFailIfExists      // 目标文件存在时是否覆盖
);

DeleteFile

Delete函数用于删除指定路径下的文件,其语法格式如下:

BOOL DeleteFile(
  LPCWSTR lpFileName  //要删除的文件的路径
);	

FindFirstFile

FindFirstFile 函数用于查找指定目录中的第一个文件或子目录,并返回句柄以供以后的查找使用,通过该句柄可以遍历该目录下的所有符合条件的文件或目录,其语法格式如下所示:

HANDLE FindFirstFile(
    LPCTSTR lpFileName,         // 文件名或路径模板
    LPWIN32_FIND_DATA lpFindFileData   // 指向 WIN32_FIND_DATA结构的指针
);

FindNextFile

FindNextFile 函数是在使用 FindFirstFile 函数后,用于在指定的目录中继续查找符合条件的文件或目录的函数,其语法格式如下:

BOOL FindNextFile(
  HANDLE         hFindFile, // FindFirstFile函数返回的句柄
  LPWIN32_FIND_DATA lpFindFileData // WIN32_FIND_DATA 结构体指针,保存查找到的文件信息
);

以下代码用于遍历E盘目录下的所有txt文件

include <Windows.h>
include <iostream>
include <string>

int main()
{	
    std::string path = "E:\\*.txt";
    WIN32_FIND_DATAA FindFileData;
    HANDLE hFind = FindFirstFileA(path.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE) {
        std::cerr << "Failed to find file." << std::endl;
        return 1;
    }

    do {
        std::cout << FindFileData.cFileName << std::endl;
    } while (FindNextFileA(hFind, &FindFileData));

    FindClose(hFind);  //释放文件句柄

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/2990.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C/C++之while(do-while)详细讲解

目录 while循环有两个重要组成部分&#xff1a; while 是一个预测试循环 无限循环 do-while 循环 while循环有两个重要组成部分&#xff1a; 进行 true 值或 false 值判断的表达式&#xff1b;只要表达式为 true 就重复执行的语句或块&#xff1b;图 1 显示了 while 循环的…

GIS开源库GEOS库学习教程(一):编译及示例代码

1、介绍 GEOS库是一个集合形状的拓扑关系操作实用库&#xff0c;简单得说&#xff0c;就是判断两个几何形状之间关系和对两个几何形状进行操作以形成新的几何形状的库。GEOS是仿照JTS库做的&#xff0c;是JTS的C实现。下面是JTS Topology Suite (JTS) 拓扑运算函数库的介绍&…

Android 自定义View 之 Mac地址输入框

Mac地址输入框前言正文一、什么是View?二、什么是自定义View三、自定义View① 构造方法② XML样式③ 测量④ 绘制1. 绘制方框2. 绘制文字⑤ 输入1. 键盘布局2. 键盘接口3. 键盘弹窗4. 显示键盘5. 处理输入四、使用自定义View五、源码前言 在日常工作开发中&#xff0c;我们时长…

Ubuntu下载、配置、安装和编译opencv

1 安装相关依赖安装opencv前&#xff0c;需要先准备好编译器、相关依赖sudo apt-get install gcc g cmake vim sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev sudo apt-get install libgtk2.0-…

MySQL数据库实现主从同步

安装MySQL数据库8.0.32 前言 今天来学习数据库主从同步的原理及过程&#xff0c;数据库主要是用来存储WEB数据&#xff0c;在企业当中是极为重要的&#xff0c;下面一起来看下。 1.1 数据库做主从的目的 MySQL主从复制在中小企业&#xff0c;大型企业中广泛使用&#xff0c…

类和对象 - 下

本文已收录至《C语言》专栏&#xff01; 作者&#xff1a;ARMCSKGT 目录 前言 正文 初始化列表 成员变量的定义与初始化 初始化列表的使用 变量定义顺序 explicit关键字 隐式类型转换 自定义类型隐式转换 explicit 限制转换 关于static static声明类成员 友元 友…

重构类关系-Push Down Method函数下移四

重构类关系-Push Down Method函数下移四 1.函数下移 1.1.使用场景 超类中的某个函数只与部分&#xff08;而非全部&#xff09;子类有关。将这个函数移到相关的那些子类去。 Push Down Method (328)与Pull Up Method (322)恰恰相反。当我有必要把某些行为从超类移至特定的子…

maven的profiles功能介绍、maven自定义插件plugin

profiles maven配置文件的profiles功能类似于springboot的spring.profiles.active配置&#xff0c;指定不同的环境来读取相应的配置内容。 <profiles>标签的子标签可以包含<repository> <plugin> <dependencies> <distributionManagement>等。 …

go语言gin框架学习

让框架去做http解包封包等&#xff0c;让我们的精力用在应用层开发 MVC模式 M: model&#xff0c;操作数据库gorm view 视图 处理模板页面 contoller 控制器 路由 逻辑函数 解决gin相关代码飘红的问题 记得启用gomodule go env -w GO111MODULEon然后到相应目录下执行 go mod i…

Karl Guttag:论相机对焦技术在AR/VR中的沿用

近期&#xff0c;AR/VR光学专家Karl Guttag介绍了两家在CES 2023展出光学传感技术的公司&#xff1a;poLight和CML&#xff08;剑桥机电一体化&#xff09;。​同时介绍两家公司的原因&#xff0c;是因为他们提供了实现AR/VR“光学微动”&#xff08;Optics Micromovement&…

5.多线程学习

作者&#xff1a;爱塔居 专栏&#xff1a;JavaEE 作者简介&#xff1a;大三学生&#xff0c;喜欢总结与分享~ 文章目录 目录 文章目录 章节回顾 一、wait 和notify 二、设计模式 2.1 单例模式 章节回顾 线程安全 1.一个线程不安全的案例&#xff08;两个线程各自自增5w次&…

PyTorch 之 基于经典网络架构训练图像分类模型

文章目录一、 模块简单介绍1. 数据预处理部分2. 网络模块设置3. 网络模型保存与测试二、数据读取与预处理操作1. 制作数据源2. 读取标签对应的实际名字3. 展示数据三、模型构建与实现1. 加载 models 中提供的模型&#xff0c;并且直接用训练的好权重当做初始化参数2. 参考 pyto…

【Linux】基于阻塞队列的生产者消费者模型

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;为何要使用…

谈谈低代码的安全问题,一文全给你解决喽

低代码是一种软件开发方法&#xff0c;通过使用图形化用户界面和可视化建模工具&#xff0c;以及自动生成代码的技术&#xff0c;使得开发人员可以更快速地构建和发布应用程序。 作为近些年软件开发市场热门之一&#xff0c;市面上也涌现了许多低代码产品&#xff0c;诸如简道云…

SpringCloud:统一网关Gateway

目录 1、网关介绍 2、搭建网关服务 3、路由断言工厂 4、路由过滤器 5、全局过滤器GlobalFilter 6、过滤器执行顺序 7、跨域问题处理 1、网关介绍 网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连&#xff0c;是复杂的网络互 连设备&#xff0…

常见背包问题

一.前言若你想学习或正在学习动态规划&#xff0c;背包问题一定是你需要了解的一种题型&#xff0c;并且大多数人最初都是从背包问题入坑进而打开动态规划这一大门。背包问题分为多种&#xff0c;你可以先掌握最常见的主要是三类&#xff1a;01背包、完全背包、多重背包二.分析…

C语言--动态内存管理1

目录前言动态内存函数介绍mallocfreecallocrealloc常见的动态内存错误对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存忘记释放&#xff08;内存泄漏&#xff09;对通讯…

TCP和UDP协议的区别?

是否面向连接&#xff1a; TCP 是面向连接的传输&#xff0c;UDP 是面向无连接的传输。 是否是可靠传输&#xff1a;TCP是可靠的传输服务&#xff0c;在传递数据之前&#xff0c;会有三次握手来建立连接&#xff1b;在数据传递时&#xff0c;有确认、窗口、重传、拥塞控制机制…

Linux编辑器-vim

一、vim简述1&#xff09;vi/vim2&#xff09;检查vim是否安装2)如何用vim打开文件3)vim的几种模式命令模式插入模式末行模式可视化模式二、vim的基本操作1)进入vim&#xff08;命令行模式&#xff09;2)[命令行模式]切换至[插入模式]3)[插入模式]切换至[命令行模式]4)[命令行模…

【C语言进阶】动态内存管理

真正的人生&#xff0c;只有在经过艰难卓绝的斗争之后才能实现。 ——塞涅卡 目录 一.为什么存在动态内存分配&#xff1f; 二.动态内存管理的函数 1.malloc函数 2.free函数 ​3.calloc函数 4.realloc函数 三.常见的动态内存错误 1.对N…