MFC或C/C++中如何判断目录存在,文件/文件夹存在,亦或是文件夹存在,文件存在

news2024/11/22 15:13:45

判断的方式太多太多,这里暂时列举5中方式。
在文章开始之前,由于需要用到CString转char功能,所以先介绍一个CString转char的方法:
想知道更多参见CString与char *互转总结
由于本文使用的Unicode编码模式,所以如下:

int CIsFileExistDlg::UnicodeToChar(CString& strIn, char* pOut, int nLen)
{
	if (NULL == pOut)
	{
		return 0;
	}

	int len = WideCharToMultiByte(CP_ACP, 0, strIn, -1, NULL, 0, NULL, NULL);
	len = min(len, nLen);

	WideCharToMultiByte(CP_ACP, 0, strIn, -1, pOut, len, NULL, NULL);

	if (len <nLen)
	{
		pOut[len] = 0;
	}

	return len;

}

一、CFileFind

1、头文件

afx.h

2、功能

执行本地文件的查找(查找某个具体的文件,查找某类文件x*.x*,查找所有文件*.*

3、延伸

  • CFileFind类是CGopherFileFind和CFtpFileFind类的基类。
  • CFileFind类的构造函数::CFileFind()和关闭函数::Close(),需要成对使用。

4、CFileFind类的成员函数我根据其操作特性划分为3类:

+ 查找操作类
+ 获得文件属性类
+ 判断文件属性类。

查找操作类

  ::FindFile();
  ::FindNextFile();

获得文件属性类

  ::GetCreationTime();
  ::GetLastAccessTime();
  ::GetLastWriteTime();
  ::GetFileName();  //带后缀的文件名
  ::GetRoot();  //盘符  
  ::GetFilePath();  //全路径
  ::GetFileTitle();  //不带后缀的文件名
  ::GetFileURL();    //URL串
  ::GetLength();     //

判断文件属性类

  ::IsArchived();
  ::IsCompressed();
  ::IsDirectory();
  ::IsDots();
  ::IsHidden();
  ::IsNormal();
  ::IsReadOnly();
  ::IsSystem();
  ::IsTemporary();
  ::MatchesMask();

5、CFileFind类中成员函数使用应注意的顺序

在创建了CFileFind对象后,先执行::FindFile()函数,然后执行::FindNextFile(),然后选择执行(获得文件属性类)的函数或者(判断文件属性类)函数。

6、CFileFind类成员函数的详细分析

virtual BOOL FindFile(LPCTSTR pstrName = null,DWORD dwUnused = 0);
//该函数若返回非0 则表明执行成功,0 则表明执行不成功。
//pstrName:需要查找的文件名,例:“E:\\编程工具\\VC++\\MFC例子.rar”,“E:\\编程工具\\VC++\\MFC*.rar”,“E:\\编程工具\\VC++\\*.*”,也可以是NULL表示“*.*”。
//dwUnused:必须为0

virtual BOOL FindNextFile();
//该函数返回值非0 还有符合条件的文件, 0表示是最后一个文件。

virtual BOOL GetCreationTime(FILETIME *pFileTime) const;
virtual BOOL GetCreationTime(CTime& refTime) const;
//该函数用来获得查找到的某个文件的创建时间,返回值非0 获得创建时间成功操作,0表示执行获得创建时间失败或者FindNextFile()没有被执行的时候。
//FILETIME *:容纳时间的结构指针
//CTime&:容纳时间的对象地址

此处介绍:FILETIME和CTime相互转换的处理方法:
#FILETIME转CTime的方法:
A、CTime对象在初始化时可以传递FILETIME结构
      FILETIME ft;
      CTime time(ft);
B、将FILETIME转换为SYSTEMTIME,然后CTime对象在初始化时可以传递SYSTEMTIME结构
      FILETIME ft;
      SYSTEMTIME st;
      BOOL bSuccess = ::FileTimeToSystemTime(&ft , &st);
      CTime time(st)#CTime转FILETIME方法:
CTime time(CTime::GetCurrentTime());
SYSTEMTIME st;
time.GetAsSystemTime(st);
FILETIME ft;
::SystemTimeToFileTime(&st,&ft);

virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;
virtual BOOL GetLastAccessTime(CTime& refTime) const;
//该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。

virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;
virtual BOOL GetLastWriteTime(CTime& refTime) const;
//该函数用来获得某个文件最后被访问的时间,非0表示执行成功,0表示执行失败或者FindNextFile()函数没有执行的时候。

virtual CString GetFilePath() const;
//该函数用来获得查找到的文件绝对路径,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“E:\\编程工具\\VC++\\MFC.rar”

virtual CString GetFileName() const;
//该函数用来获得查找到的文件的全称,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“MFC.rar”

virtual CString GetFileTitle() const;
//该函数用来获得查找到的文件的名称,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“MFC”

virtual CString GetRoot() const;
//该函数用来获得查找到的文件的根目录,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“E:\\编程工具\\VC++\\”

virtual CString GetFileURL() const;
//该函数用来获得查找到的文件的URL路径,必须在执行了FindNextFile()后该函数才能执行成功。
//返回的结果是CString对象,例“file://E:\\编程工具\\VC++\\MFC.rar”

DWORD GetLength() const;
//该函数返回值获得查找到的文件的长度,必须在执行了FindNextFile()后该函数才能执行成功。

BOOL IsArchived() const;
//该函数用来判断查找的文件属性是否是档案文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功

BOOL IsCompressed() const;
//该函数用来判断查找的文件属性是否是压缩文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功

BOOL IsDirectory() const;
//该函数用来判断查找的文件属性是否是路径文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功

BOOL IsDots() const;
//该函数用来判断查找的文件属性是否是“.”,“..”,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功

BOOL IsHidden() const;
//该函数用来判断查找的文件属性是否隐藏文件,非0表示是,0表示不是。必须在执行了FindNextFile()后该函数才能执行成功

BOOL IsNormal() const;
//该函数用来判断查找的

7、例子

CFileFind fFile;
BOOL bRet = fFile.FindFile(strPath);
if (bRet)
{
	std::cout << "CFileFind:" << "文件或者文件夹查找成功" << std::endl;
	std::cout << std::endl;
	while (bRet)
	{
		bRet = fFile.FindNextFile();
		if (fFile.IsDots())
		{
			continue;
		}

		if (fFile.IsDirectory())
		{
			std::cout << "CFileFind:" << "文件夹查找成功" << std::endl;
			std::cout << std::endl;
		}
		else
		{
			std::cout << "CFileFind:"<< "文件查找成功" << std::endl;
			std::cout << std::endl;
		}
	}
}

二、stat 函数

头文件

#include<sys/stat.h>
或者
#include<unistd.h>

函数原型

//**函数说明:**stat函数获取file_name指向文件的文件状态,并将文件信息保存到结构体buf中,
//执行成功返回0,失败返回-1,错误代码存于errno
 int stat(const char * file_name, struct stat * buf)
//结构体struct stat的参数说明:
struct stat
{
    dev_t st_dev; //device 文件的设备编号
    ino_t st_ino; //inode 文件的索引节点
    mode_t st_mode; //protection 文件的类型和存取的权限
    nlink_t st_nlink; //number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.
    uid_t st_uid; //user ID of owner 文件所有者的用户识别码
    gid_t st_gid; //group ID of owner 文件所有者的组识别码
    dev_t st_rdev; //device type 若此文件为装置设备文件, 则为其设备编号
    off_t st_size; //total size, in bytes 文件大小, 以字节计算
    unsigned long st_blksize; //blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.
    unsigned long st_blocks; //number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.
    time_t st_atime; //time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、utime、read、write 与tructate 时改变.
    time_t st_mtime; //time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、utime 和write 时才会改变
    time_t st_ctime; //time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、权限被更改时更新
};
//st_mode说明:
1、S_IFMT 0170000 文件类型的位遮罩
2、S_IFSOCK 0140000 scoket
3、S_IFLNK 0120000 符号连接
4、S_IFREG 0100000 一般文件
5、S_IFBLK 0060000 区块装置
6、S_IFDIR 0040000 目录
7、S_IFCHR 0020000 字符装置
8、S_IFIFO 0010000 先进先出
9、S_ISUID 04000 文件的 (set user-id on execution)10、S_ISGID 02000 文件的 (set group-id on execution)11、S_ISVTX 01000 文件的sticky 位
12S_IRUSR (S_IREAD) 00400 文件所有者具可读取权限
13S_IWUSR (S_IWRITE)00200 文件所有者具可写入权限
14S_IXUSR (S_IEXEC) 00100 文件所有者具可执行权限
15、S_IRGRP 00040 用户组具可读取权限
16、S_IWGRP 00020 用户组具可写入权限
17、S_IXGRP 00010 用户组具可执行权限
18、S_IROTH 00004 其他用户具可读取权限
19、S_IWOTH 00002 其他用户具可写入权限
20、S_IXOTH 00001 其他用户具可执行权限上述的文件类型在 POSIX 中定义了检查这些类型的宏定义
21S_ISLNK (st_mode) 判断是否为符号连接
22S_ISREG (st_mode) 是否为一般文件
23S_ISDIR (st_mode) 是否为目录
24S_ISCHR (st_mode) 是否为字符装置文件
25S_ISBLK (s3e) 是否为先进先出
26S_ISSOCK (st_mode) 是否为socket 若一目录具有sticky 位 (S_ISVTX), 则表示在此目录下的文件只能被该文件所有者、此目录所有者或root 来删除或改名.

举例

char cPath[128] = { 0 };
struct stat buff;
int nLen = UnicodeToChar(strPath, cPath, strPath.GetLength());
int nRet = -1;
if (nLen > 0)
{
	nRet = stat(cPath, &buff);
	if (0 == nRet ) //文件或者目录存在
	{
		if (S_IFREG & buff.st_mode)
		{
			//文件存在
			std::cout << "stat:" << cPath << "文件查找成功" << std::endl;
			std::cout << std::endl;
		}

		if (S_IFDIR & buff.st_mode)
		{
			//文件夹存在
			std::cout << "stat:" << cPath << "文件夹查找成功" << std::endl;
			std::cout << std::endl;
		}
	}
}

三、PathFileExists

头文件

#include <shlwapi.h>
#pragma comment(lib,"Shlwapi.lib") //如果没有这行,会出现link错误

功能

该函数可以检测文件或目录是否存在!

原型

BOOL PathFileExists ( __in LPCTSTR pszPath );
//Parameters参数pszPath[in] 类型:LPCTSTR,需要判断的文件或文件夹名
//存在该文件,则返回TRUE, 相反,返回FALSE.

举例

if (PathFileExists(strPath))
{
	//文件或文件夹存在
	std::cout << "PathFileExists:" << "文件或文件夹查找成功" << std::endl;
	std::cout << std::endl;
}

四、CFileStatus

功能

获取指定文件的状态信息

参数

rStatus 要获取状态信息的 CFileStatus 结构的引用。 CFileStatus 结构具有下列字段:
CTime m_ctime 文件创建日期和时间。
CTime m_mtime 文件的上次更新的日期和时间。
CTime m_atime 文件用于读取最后访问的日期和时间。
ULONGLONG m_size 文件的逻辑大小(以字节为单位),如报告DIR命令。
BYTE m_attribute 文件的属性字节。
char m_szFullName[_MAX_PATH] 在Windows字符集的绝对文件名。
lpszFileName 在路径所需文件的Windows字符集的字符串。 路径可以是相对路径或绝对的,也可以包含网络路径名。
pTM 为CAtlTransactionManager对象的指针

返回值

如果指定的文件的状态信息成功获取,返回TRUE; 否则,FALSE。

说明

GetStatus 的非静态版本检索打开文件的状态信息与特定 CFile 对象。 GetStatus 的静态版本获取从特定文件路径的文件状态,而不会实际打开文件。 这将用于测试文件是否存在以及访问权限很有用。

CFileStatus 结构的 m_attribute 成员引用设置的文件属性。 CFile 选件类提供 Attribute 枚举类型,因此文件属性可以指定标记:

enum Attribute {
normal = 0x00,
readOnly = 0x01,
hidden = 0x02,
system = 0x04,
volume = 0x08,
directory = 0x10,
archive = 0x20
};

原型

BOOL GetStatus( 
   CFileStatus& rStatus  
) const; 
 
static BOOL PASCAL GetStatus( 
   LPCTSTR lpszFileName, 
   CFileStatus& rStatus, 
   CAtlTransactionManager* pTM = NULL 
);

例子

CFileStatus FileStatus;
BOOL bFileExists = CFile::GetStatus(strPath, FileStatus);
if (bFileExists)
{
	//文件或文件夹存在
	std::cout << "CFileStatus:" << "文件或文件夹查找成功" << std::endl;
	std::cout << std::endl;
}

五、access

头文件

unistd.h
或者
io.h

功能

access( )函数:用于文件读取,判断文件是否存在,并判断文件是否可写。Linux中,函数为access();标准C++中,该函数为_access,两者的使用方法基本相同

原型

access(const char *pathname, int mode);//位于<unistd.h>中
int _access(const char *pathname, int mode);//位于<io.h>中

pathname 为文件路径或目录路径 mode 为访问权限

如果文件具有指定的访问权限,则函数返回0;如果文件不存在或者不能访问指定的权限,则返回-1.

mode的值和含义如下所示:

00——只检查文件是否存在
02——写权限
04——读权限
06——读写权限

例子

nRet = _access(cPath, S_OK);
if (0 == nRet)
{
	//文件或者文件夹存在
	std::cout << "_access:" << cPath << "文件或文件夹查找成功" << std::endl;
	std::cout << std::endl;
}

整体测试代码

void CIsFileExistDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist");

	//方法一:CFileFind
	CFileFind fFile;
	BOOL bRet = fFile.FindFile(strPath);
	if (bRet)
	{
		std::cout << "CFileFind:" << "文件或者文件夹查找成功" << std::endl;
		std::cout << std::endl;
		while (bRet)
		{
			bRet = fFile.FindNextFile();
			if (fFile.IsDots())
			{
				continue;
			}

			if (fFile.IsDirectory())
			{
				std::cout << "CFileFind:" << "文件夹查找成功" << std::endl;
				std::cout << std::endl;
			}
			else
			{
				std::cout << "CFileFind:"<< "文件查找成功" << std::endl;
				std::cout << std::endl;
			}
		}
	}

	//方法二:stat
	char cPath[128] = { 0 };
	struct stat buff;
	int nLen = UnicodeToChar(strPath, cPath, strPath.GetLength());
	int nRet = -1;
	if (nLen > 0)
	{
		nRet = stat(cPath, &buff);
		if (0 == nRet ) //文件或者目录存在
		{
			if (S_IFREG & buff.st_mode)
			{
				//文件存在
				std::cout << "stat:" << cPath << "文件查找成功" << std::endl;
				std::cout << std::endl;
			}

			if (S_IFDIR & buff.st_mode)
			{
				//文件夹存在
				std::cout << "stat:" << cPath << "文件夹查找成功" << std::endl;
				std::cout << std::endl;
			}
		}
	}

	//方式三:PathFileExists
	if (PathFileExists(strPath))
	{
		//文件或文件夹存在
		std::cout << "PathFileExists:" << "文件或文件夹查找成功" << std::endl;
		std::cout << std::endl;
	}

	//方式四:CFileStatus
	CFileStatus FileStatus;
	BOOL bFileExists = CFile::GetStatus(strPath, FileStatus);
	if (bFileExists)
	{
		//文件或文件夹存在
		std::cout << "CFileStatus:" << "文件或文件夹查找成功" << std::endl;
		std::cout << std::endl;
	}

	//方式五: access
	//包含 io.h

	nRet = _access(cPath, S_OK);
	if (0 == nRet)
	{
		//文件或者文件夹存在
		std::cout << "_access:" << cPath << "文件或文件夹查找成功" << std::endl;
		std::cout << std::endl;
	}
}

测试效果

如图:

1、当输入为目录

CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist\\");

在这里插入图片描述

2、当输入为文件夹

CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist");

在这里插入图片描述

2、当输入为文件

CString strPath = _T("D:\\DemoTest\\IsFileExist\\IsFileExist\\IsFileExistDlg.cpp");

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

链动2+1商业模式的玩法是怎么样的?

如果你感觉自己的产品卖不掉&#xff0c;很可能是因为缺乏一种成功业务模型&#xff0c;因此我们来聊聊运营商业运营模式理论&#xff1a;从一个销售产品到一个商业运营模式的高速发展&#xff0c;我们不能把它简单的当做是一种营销方法&#xff0c;也就是一种产品的营销方法。…

六、MySQL 数据库练习题1(包含前5章练习题目及答案)

文章目录一、数据库概述练习题二、MySQL 环境搭建练习题三、查询练习MySQL 数据库练习题(包含前5章所有知识点及答案) 前置知识&#xff1a; 一、数据库开发与实战专栏导学及数据库基础概念入门 二、MySQL 介绍及 MySQL 安装与配置 三、MySQL 数据库的基本操作 四、MySQL 存储…

PrimalSQL 2023 Crack

PrimalSQL 2023 使数据库查询开发和测试变得轻而易举&#xff0c;无论您的数据库类型或供应商如何。 通过单个工具支持多个数据库提供程序。 Access、SQL Server、SQL Server Compact、MySQL、Oracle、ODBC、OLEDB、Sybase 等。 使用Visual Query Builder构建复杂的查询。 使…

Steam/CSGO游戏搬砖1月行情分析及应对方法

Steam/CSGO游戏搬砖1月行情分析及应对方法 这几天&#xff0c;我看很多地方还在对外宣称说这个项目有百分之十几&#xff0c;二三十的利润率&#xff0c;多么无敌和暴利&#xff01; 天啦 &#xff0c;这些人为了能割到小白的韭菜真是无所不用其极&#xff0c;什么牛都能吹得出…

外包和外派

前言 简单介绍下人们常说的外包是什么&#xff0c;应届生未出社会没有经验&#xff0c;避免求职过程中的一些坑。 文章目录前言一、什么是外包&#xff1f;1、简介1、项目外包2、人力外包二、外包公司有哪些&#xff1f;三、优缺点1、优点2、缺点四、选择一、什么是外包&#x…

海思SS928V100开发(2)镜像烧录

1. 开发板没有uboot 在\01.software\pc\ToolPlatform下,打开烧写工具ToolPlatform如下: 选择 “烧写eMMC”,并添加fastboot,kernel,rootfs,如下图: 然后点击 烧写,进入烧写模式(注意:检查串口选择是否正确,传输方式选择 网口): 烧写完成uboot,kernel和rootf后的…

流媒体协议之RTMP详解

流媒体协议之RTMP详解 文章目录流媒体协议之RTMP详解1 RTMP概述2 RTMP交互过程2.1 握手协议2.2 RTMP分块&#xff08;chunk&#xff09;2.3 协议控制消息&#xff08;Protocol Control Message&#xff09;2.4 RTMP Message Format2.5 不同类型的RTMP Message2.6 RTMP Massage和…

【Linux多线程编程】7. 线程锁(4)——信号量

前言 上篇文章Linux多线程编程】6. 线程锁&#xff08;3&#xff09;——条件变量 介绍了使用条件变量实现多线程同步的方式&#xff0c;而条件变量一般与互斥锁一同配合。本文介绍多线程同步的另一种方式——信号量&#xff0c;使用比条件变量简单&#xff0c;也用来解决生产…

【Ansible】ansible Playbook

文章目录一、Ad-Hoc 的问题二、PlayBook 是什么三、YAML 学习1.yaml 特点2.基本语法四、 Playbook 的编写1.play 的定义2.Play 属性3.一个完整的剧本4. tasks 属性中任务的多种写法5.具有多个 play 的 playbook6. 如何对 playbook 进行语法校验下面校验的方法&#xff0c;只能校…

想要申请双软认证 这九大标准你满足吗

申请双软认证的优势有很多&#xff0c;最主要的就是能够节省企业的税收支出&#xff0c;减少成本&#xff0c;企业的利润就会增加&#xff0c;企业也能够发展得更好了。 要申请双软认证&#xff0c;企业就需要及时的了解双软认证的要求&#xff0c;不光是要有软件著作权&#…

编写jinjia2模板和角色部分 ansible(6)

目录 题目&#xff1a; 1、jinjia2模板&#xff1a; 编写hosts.j2&#xff0c;内容如下(主机名和ip地址使用变量)&#xff1a; &#xff08;1&#xff09;Welcome to 主机名 &#xff01;&#xff08;比如servera.lab.example.com&#xff09; My ip is ip地址. &#xff…

虹科新品 | 什么是光纤微动开关?(上)

01 什么是光纤微动开关 # 光纤微动开关结合了机械开关和光中断器的优点以及光纤波导的非金属性 光纤微动开关有一个确定的机械开关点&#xff0c;提供触觉反馈 光中断器没有电子机械部件&#xff0c;因此具有高可靠性 光纤是非金属的&#xff0c;它的信号损失几乎为零&#x…

苹果中国官网上线智能家居板块,蓝牙BLE在智能家居的应用

近期苹果中国区官网已上线单独的家居板块&#xff08;Apple Home&#xff09;。页面显示&#xff0c;家居板块主要分为三个品类&#xff1a;HomePod、Home App&#xff08;家庭 App&#xff09;以及智能家居配件。 据了解&#xff0c;智能家居单品均为第三方出品&#xff0c;虽…

OpenWrt 在没有80\443端口、不能dns验证的情况下为自己的域名申请免费ssl证书

适用范围 本方法适用于使用OpenWrt 在没有80\443端口、不能dns验证的情况下为自己的域名申请免费ssl证书。 提示&#xff1a; 1、如果你的网络的80或者443端口是开放状态&#xff0c;可直接使用https://letsencrypt.org/进行ssl申请&#xff0c;使用acme.sh脚本可快速完成。 2…

枚举类与注解

文章目录一、枚举类的使用枚举类的理解枚举类的定义Enum类的常用方法Enum类的实现接口二、注解&#xff08;Annotation&#xff09;说明如何自定义注解JDK提供的4种元注解通过反射获取注解信息&#xff08;到反射再讲&#xff09;JDK8注解的新特性每日一考一、枚举类的使用 枚…

Node.js教程笔记(二)模块化

学习目标 1、能够说出模块化的好处 2、能够知道CommonJS规定了哪些内容 3、能够说出NodeJS中模块的三大分类各是什么 4、能够使用npm管理包 5、能够了解什么是规范的包结构 6、能够了解模块的加载机制 目录 1、模块化的基本概念 2、NodeJS中模块的分类 3、npm与包 4…

Django项目使用wangeditor方法

一、环境&#xff1a; python&#xff1a; 3.8 Django &#xff1a;3.2.16 wangeditor&#xff1a; v4 &#xff08;官方文档地址&#xff1a;wangEditor&#xff09; JS文件下载&#xff1a;https://download.csdn.net/download/weixin_47401101/87379142 编译器&#xff1…

日志分析工具--花两天时间为自己开发个小工具值得吗?

这两天忙里偷闲整理开发了个小的日志分析工具&#xff0c;没错&#xff0c;是给自己使用的&#xff0c;工欲善其事必先利其器。 先说一下痛点&#xff0c; 1、经常会遇到需要在外网服务器上调试的情况&#xff0c;此时只能通过日志来调试信息。 2、当使用记事本打开日志文件后&…

windows驱动开发-WDF编程

文章目录前言WDF编程前的准备工作WDF编程创建驱动对象创建设备对象设备对象的回调函数链表操作驱动的测试代码前言 注&#xff1a;本文的完整代码见仓库 18-WDF-reflect 代码参考自&#xff1a;junjiexing/libredirect 我不是从事驱动开发的专业人员&#xff0c;打酱油需要用…

区块链Fabric-从入门到实战(二) Fabric环境搭建

Fabric ubuntu16虚拟机环境搭建Ubuntu16镜像ubuntu-16.04.3-server-amd64.iso &#xff08;如有需要&#xff0c;私信我&#xff09;修改软件源cd /etc/apt/sudo cp sources.list sources.list.baksudo gedit sources.listdeb-src http://mirror.neu.edu.cn/ubuntu/ xenial mai…