河南网站建设公司,牟平建设企业网站,响应式网站开发pdf,h5建站免费一、缓存文件系统 ANSI C标准中的C语言库提供了fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等标准函数#xff0c;这些函数在不同的操作系统中应该调用不同的内核API#xff0c;从而支持开发者跨平台实现对文件的访问。 在Lin…一、缓存文件系统 ANSI C标准中的C语言库提供了fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等标准函数这些函数在不同的操作系统中应该调用不同的内核API从而支持开发者跨平台实现对文件的访问。 在Linux环境下fopen是对open的封装open系列是 POSIX 定义的是UNIX系统里的system call。Linux环境下一切设备皆是文件一切设备皆是以文件的形式进行操作如网络套接字、硬件设备等对于Linux系统内核而言文本文件和二进制代码文件并无区别而open、write、read这些函数通过操作系统的功能对文件进行读写是系统级的输入输出它不设文件结构体指针只能读写二进制文件。 不同于open、write这些函数fopen 、fread这些函数是标准的C库函数更具有可移植性几乎可以可移植到任何操作系统。在实际项目中尤其是上位应用中一般是用fopen 、fread这些函数来操作普通文件fopen返回一个文件指针就可以利用文件指针操作文件其可以读取一个结构数据并支持缓冲IO。由于支持缓存IO因此fopen 、fread这些函数在处理稍大的文件时系统自动分配缓存则读出此文件等操作要比open、write这些函数效率高。 因此fopen 、fread是属于缓冲文件系统系统在内存中开辟一个“缓冲区”为程序里每一个文件使用当执行读文件操作时从磁盘文件将数据先读入内存“缓冲区”装满后再从内存“缓 冲区”依次读入接收的变量。执行写文件操作时也是先将数据写入内存“缓冲区”待内存“缓冲区”装满后再写入文件。 fopen 函数返回的是一个FILE结构指针借助于文件结构体指针FILE *就可以实现对文件管理通过文件指针对文件进行访问即可以读写字符、字符串、格式化数据也可以读写二进制数据。 fopen 函数原型是FILE *fopen(const char* file, const char* model)可以指定一个文件路径来打开一个文件成功时返回非NULL的FILE *。fclose, fread, fwrite, fgetc, fgets, fputc, fputs等函数都是基于该文件指针进行操作。
二、文件访问开发设计 2.1 文件接口服务设计 本文将通过fopen, fclose, fread, fwrite, fgetc, fgets等系列函数实现跨windows和linux的文件访问进行数据读取、写入并在此基础上提供对文件内容行读取与写入、列分割等快捷功能同时实现都目录及文件的创建、存在判定、删除、重命名等操作。 例如
//文件操作相关
bool writeToFile(const char *ptr,const std::string path, const std::string mode);//写入一段内容
bool writeListInfo(std::vectorstd::string list,const std::string path);//写入多行内容
bool readFromFile(char *ptr, int size, int buf_size,const std::string path, const std::string mode);//读取一段内容
bool readListInfo(std::vectorstd::vectorstd::string list,const std::string path);//读取多行内容
bool readListInfo(std::vectorstd::vectorstd::string list,const std::string path);//读取多行内容,每行按空格分割//目录相关
bool createDir(std::string _dir); //创建目录
bool isExistDir(std::string _dir); //判断指定目录是否存在
bool getCurrentDir(char* dir_, int len_);//获取当前目录路径//文件相关
void renameFile(const std::string _oldName, const std::string _newName);//重命名文件
void removeFile(const std::string _Name); //删除文件
bool isExist(std::string file); //文件(绝对及相对路径名)是否存在
bool isExist(std::string dir,std::string file); //某目录下某文件是否存在 文件的读写伪代码如下
//打开
FILE *m_fil ::fopen(path,mode);
//读取
int size fread(buf, static_castint(sizeof(char)), (size_t)buf_size,m_fil);
//写入
::fwrite(buf, static_castint(sizeof(char)), buf_len,m_fil );
//循环读取每行数据
while(NULL!::fgets(buf,buf_size,m_fil)) 在目录及文件名处理方面伪代码如下
//获取路径
char* dir getcwd(dir_, len_);
//访问目录-linux
DIR* dfd opendir(_dir.c_str());
//访问目录-win
bool ret _access(_dir.c_str(),0);
//创建目录(win _mkdir)
int ret mkdir(_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);//文件是否存在-win
_finddata_t fileInfo;
intptr_t hFile _findfirst(file,fileInfo);
//文件是否存在-Linux是否能打开文件来判断
::fopen
//重命名文件
int ret rename(_oldName,_newName);
//删除文件
int ret remove(_Name); 行内容按空格或“.”划分:
//将采用空格间隔的字符串划分成子字符串集
std::string buffer; // Have a buffer string
std::stringstream _lineStr(_lineInfo); // Insert the string into a stream
std::vectorstd::string _lineList; // Create vector to hold our words
while(_lineStr buffer)
{_lineList.push_back(buffer);
}//将采用,间隔的字符串划分成子字符串集
void pyfree::getNumberFromStr(std::vectorstd::string ids, std::string idsStr)
{if(idsStr||NULLidsStr)return;std::string id ;for(unsigned int i0,idSize static_castunsigned int(idsStr.size()); iidSize; i){if(,idsStr[i]){//use str , to dirve the idsStr;if(!id){ids.push_back(id);id.clear();id ;}else{ids.push_back(id);}}else if(i(idSize-1)){if(!id){ids.push_back(id);id.clear();id ;}}else{id.push_back(idsStr[i]);}}
} 在实际项目中往往会遇到中文情况尤其是在linux系统下不少文件是采用ascii或gbk、gb2312等存储编码格式但在程序内处理数据是大多是采用utf-8编码格式因此必要时还需要对读取到的内容做编码格式转换。
//增加codef类型参数来确定是否进行编码格式转换
bool readListInfo(std::vectorstd::vectorstd::string list,const std::string path,int codef0);//读取多行内容
bool readListInfo(std::vectorstd::vectorstd::string list,const std::string path,int codef0);//读取多行内容,每行按空格分割 2.2 工程及代码设计 创建项目目录结构如下
myfile_testbinbuild_win //win编译过程文件路径build_linux //Linux编译过程文件目录src //文件接口源码test //接口调用示例CMakeLists.txt //cmake工程配置文件编译指令.txt //编辑及运行命令 在src目录下创建File.h/cpp源文件File.h设计如下File.cpp见附录
#if _MSC_VER 1000
#pragma once
#endif // _MSC_VER 1000#ifndef _FILE_H_
#define _FILE_H_
/************************************************************************Copyright 2023-02-07, pyfree**File Name : File.h*File Mark : *Summary : *文本读写函数类**Current Version : 1.00*Author : pyfree*FinishDate :**Replace Version :*Author :*FinishDate :************************************************************************/
#include string
#include vector
#include stdio.hnamespace pyfree
{/*** 向指定文件写入数据* param ptr {const char*} 待写入内容* param path {string} 文件名* param mode {string} 写入模式,等同于fopen或open函数的写入模式* return {bool} */bool writeToFile(const char *ptr,const std::string path, const std::string mode);/*** 向指定文件追写数据* param list {vector} 待写入内容容器,每项作为一行写入* param path {string} 文件名* return {bool} */bool writeListInfo(std::vectorstd::string list,const std::string path);/*** 从指定文件读取数据* param ptr {char*} 待读取内容指针* param size {int} 实际读取大小* param buf_size {int} 待读取指针存储空间大小* param list {vector} 待写入内容容器,每项作为一行写入* param path {string} 文件名* param mode {string} 读取模式,等同于fopen或open函数的读取模式* return {bool} */bool readFromFile(char *ptr, int size, int buf_size,const std::string path, const std::string mode);/*** 从指定文件中读取文件每一行的字符串如果行中存在空格划分该行字符串并装在到容器中* param list {vectorvector} 读取内容容器,每一行作为一项载入容器,每行内容分割后容器装载* param path {string} 文件名* param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}* return {bool} */bool readListInfo(std::vectorstd::vectorstd::string list,const std::string path,int codef0);/*** 从指定文件中读取文件每一行的字符串如果行中存在,间隔划分该行字符串并装在到容器中* param list {vectorvector} 读取内容容器,每一行作为一项载入容器,每行内容分割后容器装载* param path {string} 文件名* param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}* return {bool} */bool readListInfo_dot(std::vectorstd::vectorstd::string list,const std::string path,int codef0);/*** 从指定文件中读取文件每一行的字符串并装在到容器中* param list {vector} 读取内容容器,每一行作为一项载入容器* param path {string} 文件名* param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}* return {bool} */bool readListInfo(std::vectorstd::string list,const std::string path,int codef0);/*** 将采用,间隔的字符串划分成子字符串集,被readListInfo_dot调用* param ids {vector} 读取内容容器* param idsStr {string} 被检查字符串* return {void} */void getNumberFromStr(std::vectorstd::string ids, std::string idsStr);/*** 从指定文件目录下读取指定扩展名的文件名,返回结果包含扩展名* param directory {string} 文件目录* param extName {string} 扩展名* param fileNames {vector} 读取结果* return {bool} 是否成功*/void getAllFileName_dot(const std::string directory, const std::string extName, std::vectorstd::string fileNames);/*** 从指定文件目录下读取指定扩展名的文件名,返回结果不包含扩展名* param directory {string} 文件目录* param extName {string} 扩展名* param fileNames {vector} 读取结果* return {bool} 是否成功*/void getAllFileName(const std::string directory, const std::string extName, std::vectorstd::string fileNames);/*** 从指定文件目录下读取指定扩展名的文件名,被getAllFileName_dot和getAllFileName调用* param directory {string} 文件目录* param extName {string} 扩展名* param fileNames {vector} 读取结果* param f {bool} 是否包含扩展名* return {bool} 是否成功*/void getAllFileNamePrivate(const std::string directory, const std::string extName, std::vectorstd::string fileNames, bool ffalse);/*** 读取文件修改时间* param file_path {string} 文件名(全路径)* return {uint} 时间(time_t)*/unsigned int getFileModifyTime(const std::string file_path);/*** 重命名文件* param _oldName {string} 旧文件名* param _newName {string} 新文件名* return {void}*/void renameFile(const std::string _oldName, const std::string _newName);/*** 删除文件* param _Name {string} 文件名(全路径)* return {void}*/void removeFile(const std::string _Name);/*** 文件是否存在* param file {string} 文件名(全路径)* return {bool}*/bool isExist(std::string file);/*** 文件在指定目录下是否存在* param dir {string} 指定目录* param file {string}* return {bool}*/bool isExist(std::string dir,std::string file);/*** 将多很节点的xml表述文件重新批量重写为单根节点的xml文件集* param _xmlFile {string} 文件名* param _xmlDir {string} 目录* param _xmlDiv {string} 根节点名* param utfFlag {bool} 是否utf编码* return {void}*/void divXmlFile(std::string _xmlFile,std::string _xmlDir,std::string _xmlDiv,bool utfFlag);/*** 创建文件目录* param _dir {string} 目录名* return {bool}*/bool createDir(std::string _dir);/*** 文件目录是否存在* param _dir {string} 目录名* return {bool}*/bool isExistDir(std::string _dir);/*** 获取程序当前所在目录* param dir_ {char*} 目录名* return {bool}*/bool getCurrentDir(char* dir_, int len_);
};#endif //_FILE_H_在src目录下创建strTrim.h,用来去除字符串前后空格。
#if _MSC_VER 1000
#pragma once
#endif // _MSC_VER 1000#ifndef _STRTRIM_H_
#define _STRTRIM_H_
/************************************************************************Copyright 2023-02-08, pyfree**File Name : strTrim.h*File Mark : *Summary : *字符串前后空格处置函数**Current Version : 1.00*Author : pyfree*FinishDate :**Replace Version :*Author :*FinishDate :************************************************************************/#include string
#include vector
#include algorithm
#include functionalnamespace pyfree
{
/*** 删除字符串前面的空格* param ss {string} 传入字符串* return {string } 返回字符串*/
inline std::string lTrim(std::string ss)
{ss.erase(0, ss.find_first_not_of( \t)); //return ss;
}
/*** 删除字符串后面的空格* param ss {string} 传入字符串* return {string } 返回字符串*/
inline std::string rTrim(std::string ss)
{ss.erase(ss.find_last_not_of( \t) 1); //return ss;
}
/*** 删除字符串前面和后面的空格* param ss {string} 传入字符串* return {string } 返回字符串*/
inline std::string trim(std::string st)
{lTrim(rTrim(st));return st;
}
/*** 擦除字符串后面的结束字符* param ss {string} 传入字符串* return {string } 返回字符串*/
inline void trimEnd(std::string dir)
{if(dir.empty()){return;}//some line is NULLif(dir.size()1){return;}while(dir[dir.length()-1] \n|| dir[dir.length()-1] \r|| dir[dir.length()-1] \t){dir dir.substr(0,dir.size()-1);}
};};#endif // 在src目录下创建strchange.h/cpp用来处理字符编码格式转换strchange.h内容如下strchange.cpp见附录。
#ifdef WIN32
#if _MSC_VER 1000
#pragma once
#endif // _MSC_VER 1000
#endif#ifndef _STR_CHANGE_H_
#define _STR_CHANGE_H_/************************************************************************Copyright 2023-02-07, pyfree**File Name : strchange.h*File Mark : *Summary : *字符编码相关函数集**Current Version : 1.00*Author : pyfree*FinishDate :**Replace Version :*Author :*FinishDate :************************************************************************/#include stringnamespace pyfree
{
#ifdef WIN32
//UTF-8 to Unicode
std::wstring Utf82Unicode(const std::string utf8string);
//unicode to ascii
std::string WideByte2Acsi(std::wstring wstrcode);
//ascii to Unicode
std::wstring Acsi2WideByte(std::string strascii);
//Unicode to Utf8
std::string Unicode2Utf8(const std::wstring widestring);
//
std::wstring stringToWstring(const std::string str);
//
std::string wstringToString(const std::wstring wstr);
#endif#ifdef __linux__
int code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen);
int u2g(char *inbuf,int inlen,char *outbuf,int outlen);
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen);
int u2a(char *inbuf,int inlen,char *outbuf,int outlen);
int a2u(char *inbuf,int inlen,char *outbuf,int outlen);
int u2k(char *inbuf,int inlen,char *outbuf,int outlen);
int k2u(char *inbuf,int inlen,char *outbuf,int outlen);
#endif//utf-8 to ascii
std::string UTF_82ASCII(std::string strUtf8Code);
//ascii to Utf8
std::string ASCII2UTF_8(std::string strAsciiCode);
};#endif //STRCHANGE_HPP在str目录下创建pfunc_print.h通过宏定义用来打印运行日志信息。
#if _MSC_VER 1000
#pragma once
#endif // _MSC_VER 1000#ifndef _PFUNC_PRINT_H_
#define _PFUNC_PRINT_H_
/************************************************************************Copyright 2022-11-06, pyfree**File Name : pfunc_print.h*File Mark : *Summary : 打印输出通用宏定义**Current Version : 1.00*Author : pyfree*FinishDate :**Replace Version :*Author :*FinishDate :************************************************************************/
typedef enum PrintLevel
{ LL_NOTICE 1, //一般输出LL_WARNING 2, //告警输出LL_TRACE 3, //追踪调试LL_DEBUG 4, //软件bugLL_FATAL 5 //致命错误
}PrintLevel;#define Print_NOTICE(log_fmt,...) \do{ \printf(L(%d)[%s:%d][%s] \nlog_fmt\n, LL_NOTICE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \}while (0) #define Print_WARN(log_fmt,...) \do{ \printf(L(%d)[%s:%d][%s] \nlog_fmt\n, LL_WARNING, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \}while (0) #define Print_TRACE(log_fmt,...) \do{ \printf(L(%d)[%s:%d][%s] \nlog_fmt\n, LL_TRACE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \}while (0) #define Print_DEBUG(log_fmt,...) \do{ \printf(L(%d)[%s:%d][%s] \nlog_fmt\n, LL_DEBUG, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \}while (0) #define Print_FATAL(log_fmt,...) \do{ \printf(L(%d)[%s:%d][%s] \nlog_fmt\n,LL_FATAL, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \}while (0) #endif在test目录下创建main.cppFile IO模块调用示例程序
#include File.h
#include pfunc_print.hint main(int argc, char* argv[])
{std::string dir_ test;std::string file_name test.txt;std::string file_ dir_ / file_name;std::string comment_ test\n;//写入信息需要自行加\n是因为实际项目使用中,有时写入数据需要连续性std::vectorstd::string comments_ ;comments_.push_back(test1 test10\n);comments_.push_back(test2,test20\n);comments_.push_back(test3,test30\n);//char cur_dir_buf[128]{0};bool ret pyfree::getCurrentDir(cur_dir_buf,128);//获取当前目录if(!ret){Print_DEBUG(getCurrentDir fail!\n);}else{Print_NOTICE(CurrentDir is %s!\n,cur_dir_buf);}//目录创建测试ret pyfree::createDir(dir_);//在当前目录创建子目录:dir_if(!ret){Print_DEBUG(createDir %s fail!\n,dir_.c_str());}else{Print_NOTICE(createDir %s success!\n,dir_.c_str());}//目是否存在ret pyfree::isExistDir(dir_);//判断子目录dir_是否存在(是否创建成功)if(!ret){Print_DEBUG(Dir %s is not exist!\n,dir_.c_str());}else{Print_NOTICE(Dir %s is exist!\n,dir_.c_str());}//单段内容写入测试ret pyfree::writeToFile(comment_.c_str(),file_,w);//重新写入,file_不存在将新建if(!ret){Print_DEBUG(writeToFile %s to %s fail!\n,comment_.c_str(),file_.c_str());}else{Print_NOTICE(writeToFile %s to %s success!\n,comment_.c_str(),file_.c_str());}//指定文件路径名判断ret pyfree::isExist(file_);//判断文件file_是否存在(或是否创建成功)if(!ret){Print_DEBUG(file_path %s is not exist!\n,file_.c_str());}else{Print_NOTICE(file_path %s is exist!\n,file_.c_str());}//指定目录及文件名判断ret pyfree::isExist(dir_,file_name);//当前目录的子目录dir_下是否存在文件名file_nameif(!ret){Print_DEBUG(Dir %s file %s is not exist!\n,dir_.c_str(),file_name.c_str());}else{Print_NOTICE(Dir %s file %s is exist!\n,dir_.c_str(),file_name.c_str());}//多行写入测试ret pyfree::writeListInfo(comments_,file_); //追加写入一组内容if(!ret){Print_DEBUG(writeListInfo to %s fail!\n, file_.c_str());}else{Print_NOTICE(writeListInfo to %s success!\n, file_.c_str());}//文件内容读取测试char buf[512]{0};int readLen 0;ret pyfree::readFromFile(buf,readLen,512,file_,r);//从文件读取指定长度数据if(!ret){Print_DEBUG(readFromFile from %s fail!\n, file_.c_str());}else{Print_NOTICE(readFromFile from %s:\n%s\n, file_.c_str(),buf);}//行读取测试std::vectorstd::string list;ret pyfree::readListInfo(list,file_);//从文件按行读取数据if(!ret){Print_DEBUG(readListInfo from %s fail!\n, file_.c_str());}else{Print_NOTICE(readListInfo from %s success[%d]:, file_.c_str(),(int)list.size());for(unsigned int i0; ilist.size(); i){printf(row[%u]:%s\n,i,list.at(i).c_str());}}//空格间隔测试std::vectorstd::vectorstd::string lists;//从文件按行、列读取数据,列按空格分割ret pyfree::readListInfo(lists,file_);if(!ret){Print_DEBUG(readListInfo from %s fail!\n, file_.c_str());}else{Print_NOTICE(readListInfo from %s success[%d]:, file_.c_str(),(int)lists.size());for(unsigned int i0; ilists.size(); i){for(unsigned int j0; jlists.at(i).size(); j){printf(row[%u] col[%u]:%s,i,j,lists.at(i).at(j).c_str());}printf(\n);}}//,间隔测试lists.clear();ret pyfree::readListInfo_dot(lists,file_);//从文件按行、列读取数据,列按,分割if(!ret){Print_DEBUG(readListInfo from %s fail!\n, file_.c_str());}else{Print_NOTICE(readListInfo from %s success[%d]:, file_.c_str(),(int)lists.size());for(unsigned int i0; ilists.size(); i){for(unsigned int j0; jlists.at(i).size(); j){printf(row[%u] col[%u]:%s,i,j,lists.at(i).at(j).c_str());}printf(\n);}}std::vectorstd::string fileNames;pyfree::getAllFileName(dir_,txt,fileNames);//获取子目录dir_下的所有txt格式文件名,文件名不带扩展名if(fileNames.empty()){Print_DEBUG(getAllFileName from %s fail!\n, dir_.c_str());}else{Print_NOTICE(getAllFileName from %s success[%d]:, dir_.c_str(),(int)fileNames.size());for(unsigned int i0; ifileNames.size(); i){printf(fileName[%u]:%s \n,i,fileNames.at(i).c_str());}}fileNames.clear();pyfree::getAllFileName_dot(dir_,txt,fileNames);//获取子目录dir_下的所有txt格式文件名,文件名带扩展名if(fileNames.empty()){Print_DEBUG(getAllFileName_dot from %s fail!\n, dir_.c_str());}else{Print_NOTICE(getAllFileName_dot2 from %s success[%d]:, dir_.c_str(),(int)fileNames.size());for(unsigned int i0; ifileNames.size(); i){printf(fileName[%u]:%s \n,i,fileNames.at(i).c_str());}}dir_ test_s;//行读取测试,ANSI格式list.clear();file_ dir_/test1.ini;ret pyfree::readListInfo(list,file_,2);//从文件按行读取数据if(!ret){Print_DEBUG(readListInfo ANSI fomat from %s fail!\n, file_.c_str());}else{Print_NOTICE(readListInfo ANSI fomat from %s success[%d]:, file_.c_str(),(int)list.size());for(unsigned int i0; ilist.size(); i){printf(row[%u]:%s\n,i,list.at(i).c_str());}}//行读取测试,GB格式list.clear();file_ dir_/test2.ini;ret pyfree::readListInfo(list,file_,1);//从文件按行读取数据if(!ret){Print_DEBUG(readListInfo GB fomat from %s fail!\n, file_.c_str());}else{Print_NOTICE(readListInfo GB fomat from %s success[%d]:, file_.c_str(),(int)list.size());for(unsigned int i0; ilist.size(); i){printf(row[%u]:%s\n,i,list.at(i).c_str());}}return 0;
}2.3 编译及测试 完成后项目文件结构如下
myfile_testbinbuild_win //win编译过程文件路径build_linux //Linux编译过程文件目录src //文件接口源码File.hFile.cpppfunc_print.hstrTrim.hstrchange.hstrchange.cpptest //接口调用示例main.cppCMakeLists.txt //cmake工程配置文件编译指令.txt //编辑及运行命令 CMakeLists.txt内容如下基于cmakevs(win)或g(linux)编译工具
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (file_test)
#
if(WIN32)message(STATUS windows compiling...)add_definitions(-D_PLATFORM_IS_WINDOWS_)set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} /MT)set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} /MTd)set(WIN_OS true)
else(WIN32)message(STATUS linux compiling...)add_definitions( -D_PLATFORM_IS_LINUX_)add_definitions(-Wno-invalid-source-encoding)set(UNIX_OS true)set(_DEBUG true)endif(WIN32)#
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 指定源文件的目录,并将名称保存到变量
SET(source_h#${PROJECT_SOURCE_DIR}/src/pfunc_print.h${PROJECT_SOURCE_DIR}/src/strTrim.h${PROJECT_SOURCE_DIR}/src/strchange.h${PROJECT_SOURCE_DIR}/src/File.h)SET(source_cpp#${PROJECT_SOURCE_DIR}/src/strchange.cpp${PROJECT_SOURCE_DIR}/src/File.cpp${PROJECT_SOURCE_DIR}/test/main.cpp)#头文件目录
include_directories(${PROJECT_SOURCE_DIR}/src)if (${UNIX_OS})add_definitions(-W-fPIC-Wall# -Wall -g-Werror-Wshadow-Wformat-Wpointer-arith-D_REENTRANT-D_USE_FAST_MACRO-Wno-long-long-Wuninitialized-D_POSIX_PTHREAD_SEMANTICS-DACL_PREPARE_COMPILE-Wno-unused-parameter-fexceptions)set(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} -O0)link_directories()
# 指定生成目标
add_executable(file_test ${source_h} ${source_cpp} )
#link
target_link_libraries(file_test # -lpthread -pthread-lz -lrt -ldl
)endif(${UNIX_OS})if (${WIN_OS})set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} /wd4819)add_definitions(-D_CRT_SECURE_NO_WARNINGS-D_WINSOCK_DEPRECATED_NO_WARNINGS-DNO_WARN_MBCS_MFC_DEPRECATION-DWIN32_LEAN_AND_MEAN
)link_directories()if (CMAKE_BUILD_TYPE STREQUAL Debug)set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(file_testd ${source_h} ${source_cpp})else(CMAKE_BUILD_TYPE)set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(file_test ${source_h} ${source_cpp})endif (CMAKE_BUILD_TYPE)endif(${WIN_OS}) 编译指令如下
win:
cd myfile_test mkdir build_win cd build_win
cmake -G Visual Studio 14 2015 Win64 -DCMAKE_BUILD_TYPERelease .. -Wno-dev
#vs 命令窗口
msbuild file_test.sln /p:ConfigurationRelease /p:Platformx64linux:
cd file_test mkdir build_linux cd build_linux
cmake ..
make 按上述指令编译测试如下 先在bin目录下创建test_s文件夹并在该子目录创建test1.ini文件该文件编码格式为ANSI格式写上一些内容在该子目录创建test2.ini文件该文件编码格式为 GB格式写上一些中文内容。 启动程序测试如下 三、源码附录 File.cpp
#include File.h#include stdarg.h
#include sys/types.h
#include sys/stat.h
#include sstream
#ifdef WIN32
#include io.h
#include windows.h
#include direct.h#define getcwd _getcwd
#endif
#ifdef linux
#include string.h
#include errno.h
#include dirent.h
#include unistd.h
#endif#include strchange.h
#include strTrim.h
#include pfunc_print.hbool pyfree::writeToFile(const char *ptr,const std::string path, const std::string mode)
{FILE *m_fil NULL;m_fil ::fopen(path.c_str(),mode.c_str());if(NULL!m_fil){size_t size 0;size ::fwrite(ptr, static_castint(sizeof(char)), strlen(ptr),m_fil);::fclose(m_fil);m_fil NULL;if(size0){return true;}else{return false;}}else{m_fil NULL;return false;}
}bool pyfree::writeListInfo(std::vectorstd::string list,const std::string path)
{size_t newSize 0;FILE *new_m_filNULL;new_m_fil ::fopen(path.c_str(),a);if(NULL!new_m_fil){for(size_t i0,lSizelist.size(); ilSize; i){newSize ::fwrite(list.at(i).c_str(), static_castint(sizeof(char)), strlen(list.at(i).c_str()),new_m_fil);}::fclose(new_m_fil);}new_m_fil NULL;if(newSize0){return true;}return false;
}bool pyfree::readFromFile(char *ptr, int size, int buf_size,const std::string path, const std::string mode)
{FILE *m_filNULL;m_fil ::fopen(path.c_str(),mode.c_str());if(NULL!m_fil){size static_castint( ::fread(ptr, static_castint(sizeof(char)), (size_t)buf_size,m_fil) );::fclose(m_fil);m_fil NULL;if(size0){return true;}elsereturn false;}else{m_fil NULL;return false;}
}//读取文件每一行得字符串如果行中存在空格划分该行字符串并装在到容器中
bool pyfree::readListInfo(std::vectorstd::vectorstd::string list,const std::string path,int codef)
{FILE *m_filNULL;m_fil ::fopen(path.c_str(),r);if(NULL!m_fil){char buf[1024] {0};while(NULL!::fgets(buf,1024,m_fil)){std::string _lineInfo buf;trimEnd(_lineInfo);#ifdef __linux__switch (codef){case 1:{char buff[1024]{0};g2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;case 2:{char buff[1024]{0};a2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;default:break;}#endifstd::string buffer;// Have a buffer stringstd::stringstream _lineStr(_lineInfo);// Insert the string into a streamstd::vectorstd::string _lineList;// Create vector to hold our wordswhile(_lineStr buffer){_lineList.push_back(buffer);}list.push_back(_lineList);}::fclose(m_fil);m_fil NULL;if(list.empty()){return false;}}else{#ifdef WIN32Print_WARN(cont open %s, %d \n,path.c_str(), ::GetLastError());#endif#ifdef linuxPrint_WARN(cont open %s, %s \n,path.c_str(),strerror(errno));#endifm_fil NULL;return false;}return true;
}//将采用,间隔的字符串划分成子字符串集
void pyfree::getNumberFromStr(std::vectorstd::string ids, std::string idsStr)
{if(idsStr||NULLidsStr)return;std::string id ;for(unsigned int i0,idSize static_castunsigned int(idsStr.size()); iidSize; i){if(,idsStr[i]){//use str , to dirve the idsStr;if(!id){ids.push_back(id);id.clear();id ;}else{ids.push_back(id);}}else if(i(idSize-1)){if(!id){ids.push_back(id);id.clear();id ;}}else{id.push_back(idsStr[i]);}}
}//读取文件每一行得字符串如果行中存在,划分该行字符串并装在到容器中
bool pyfree::readListInfo_dot(std::vectorstd::vectorstd::string list,const std::string path,int codef)
{FILE *m_filNULL;m_fil ::fopen(path.c_str(),r);if(NULL!m_fil){char buf[1024] {0};std::string _lineInfo ;while(NULL!::fgets(buf,1024,m_fil)){_lineInfo buf;trim(_lineInfo);#ifdef __linux__switch (codef){case 1:{char buff[1024]{0};g2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;case 2:{char buff[1024]{0};a2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;default:break;}#endifstd::vectorstd::string _lineList;getNumberFromStr(_lineList,_lineInfo);list.push_back(_lineList);}::fclose(m_fil);m_fil NULL;if(list.empty()){return false;}}else{#ifdef WIN32Print_WARN(cont open %s, %d \n,path.c_str(), ::GetLastError());#endif#ifdef linuxPrint_WARN(cont open %s, %s \n,path.c_str(),strerror(errno));#endifm_fil NULL;return false;}return true;
}//读取文件并将每一行字符串载入容器
bool pyfree::readListInfo(std::vectorstd::string list,const std::string path,int codef)
{FILE *m_filNULL;m_fil ::fopen(path.c_str(),r);if(NULL!m_fil){char buf[512] {0};std::string _lineInfo;while(NULL!::fgets(buf,512,m_fil)){_lineInfo buf;trimEnd(_lineInfo);#ifdef __linux__switch (codef){case 1:{char buff[1024]{0};g2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;case 2:{char buff[1024]{0};a2u(buf,strlen(buf),buff,1024);_lineInfo buff;}break;default:break;}#endiflist.push_back(_lineInfo);}::fclose(m_fil);m_fil NULL;if(list.empty()){return false;}}else{#ifdef WIN32Print_WARN(cont open %s, %d \n,path.c_str(), ::GetLastError());#endif#ifdef linuxPrint_WARN(cont open %s, %s \n,path.c_str(),strerror(errno));#endifm_fil NULL;return false;}return true;
}//获得dire目录下扩展名为extName的所有文件名
void pyfree::getAllFileName_dot(const std::string directory, const std::string extName, std::vectorstd::string fileNames)
{getAllFileNamePrivate(directory,extName,fileNames,true);
}//获得dire目录下扩展名为extName的所有文件名
void pyfree::getAllFileName(const std::string directory, const std::string extName, std::vectorstd::string fileNames)
{getAllFileNamePrivate(directory,extName,fileNames);
}void pyfree::getAllFileNamePrivate(const std::string directory, const std::string extName, std::vectorstd::string fileNames,bool f)
{#ifdef WIN32_finddata_t fileInfo;intptr_t hFile;std::string filter directory;char bch static_castchar((//) 0X00FF);if(filter[filter.size()-1] ! bch){filter.push_back(bch);}filter *.;filter extName;hFile _findfirst(filter.c_str(),fileInfo);if(hFile -1){return;}do {if (extName.empty()){if ((fileInfo.attrib _A_SUBDIR)){if (0strcmp(fileInfo.name,.) || 0strcmp(fileInfo.name,..) ){continue;}fileNames.push_back(fileInfo.name);}}else{std::string name(fileInfo.name);if(f){fileNames.push_back(name);}else{fileNames.push_back(name.substr(0,name.find_last_of(.)));}// fileNames.push_back(name.substr(0,name.find_last_of(.)));}} while (_findnext(hFile,fileInfo) 0);_findclose(hFile);#endif#ifdef linuxstd::string curdir directory;if(curdir[curdir.size()-1] ! /){curdir.push_back(/);}DIR *dfd;if( (dfd opendir(curdir.c_str())) NULL ){Print_WARN(open %s error with msg is: %s\n,curdir.c_str(),strerror(errno));return;}struct dirent *dp;while ((dp readdir(dfd)) ! NULL){if (extName.empty()){if (dp-d_type DT_DIR){if ( 0strcmp(dp-d_name, .) || 0strcmp(dp-d_name, ..) ){continue;}fileNames.push_back(dp-d_name);}}else{if ( NULLstrstr(dp-d_name, extName.c_str()) ){continue;}std::string name(dp-d_name);if(f){fileNames.push_back(name);}else{fileNames.push_back(name.substr(0,name.find_last_of(.)));}}}if (NULL ! dp) {delete dp;dp NULL;}if (NULL ! dfd) {closedir(dfd);dfd NULL;}#endif
}unsigned int pyfree::getFileModifyTime(const std::string file_path)
{unsigned int ret 0;
#if defined(WIN32)_finddata_t fileInfo;intptr_t hFile;hFile _findfirst(file_path.c_str(),fileInfo);if(hFile ! -1){ret static_castunsigned int(fileInfo.time_write);}else{Print_WARN(get file %s last modify error: %d \n,file_path.c_str(), ::GetLastError());}_findclose(hFile);
#elif defined(linux)struct stat el;if(0stat(file_path.c_str(), el)){ret static_castunsigned int(el.st_mtime);}else{Print_WARN(get file %s last modify time error: %s\n,file_path.c_str(),strerror(errno));}
#elseret 0;
#endif // WIN32return ret;
}void pyfree::renameFile(const std::string _oldName, const std::string _newName)
{#ifdef WIN32_finddata_t fileInfo;intptr_t hFile;hFile _findfirst(_oldName.c_str(),fileInfo);if(hFile -1){Print_WARN(cant find file %s \n,_oldName.c_str());writeToFile(,_newName,w);return;}// do {// std::string name(fileInfo.name);// fileNames.push_back(name.substr(0,name.find_last_of(.)));// } while (_findnext(hFile,fileInfo) 0);_findclose(hFile);#endif#ifdef linuxFILE* m_fil ::fopen(_oldName.c_str(),r);if(NULLm_fil){return;}::fclose(m_fil);m_fil NULL;#endifPrint_NOTICE(%s, %s\n, _oldName.c_str(),_newName.c_str());int ret rename(_oldName.c_str(),_newName.c_str());if(0 ! ret){Print_WARN(cant rename %s to %s \n,_oldName.c_str(),_newName.c_str());return;}
}void pyfree::removeFile(const std::string _Name)
{int ret remove(_Name.c_str());if(0 ! ret){Print_WARN(cant remove %s \n,_Name.c_str());return;}
}bool pyfree::isExist(std::string file)
{#ifdef WIN32_finddata_t fileInfo;intptr_t hFile _findfirst(file.c_str(),fileInfo);if(hFile -1){return false;}_findclose(hFile);return true;#elseFILE *m_filNULL;m_fil::fopen(file.c_str(),rb);if(NULLm_fil){return false;}else{::fclose(m_fil);m_fil NULL;}return true;#endif
}bool pyfree::isExist(std::string dir,std::string file)
{std::string path dir;
#ifdef WIN32path\\;
#elsepath/;
#endifpathfile;return isExist(path);
};void pyfree::divXmlFile(std::string _xmlFile,std::string _xmlDir,std::string _xmlDiv,bool utfFlag)
{static int substationIndex 1;FILE *m_filNULL;FILE *new_m_filNULL;std::string _xmlNode?xml version\1.0\ encoding\UTF-8\?\n;_xmlNode utfFlag?ASCII2UTF_8(_xmlNode):_xmlNode;std::string _xmlHead _xmlDiv;std::string _xmlEnd /_xmlDiv;if(NULL!(m_filfopen(_xmlFile.c_str(),rb))){char buf[512] {0};while(NULL!::fgets(buf,512,m_fil)){std::string _lineInfo buf;_lineInfo utfFlag?ASCII2UTF_8(_lineInfo):_lineInfo;std::string::size_type _posH _lineInfo.find(_xmlHead);if(std::string::npos ! _posH){char newxml[256]{0};sprintf(newxml,%s\\%s_%d.xml,_xmlDir.c_str(),_xmlDiv.c_str(),substationIndex);if(NULL!(new_m_fil::fopen(newxml,a))){int newSize static_castint(::fwrite(_xmlNode.c_str(), static_castint(sizeof(char)), strlen(_xmlNode.c_str()),new_m_fil));if(newSize0){Print_WARN(newxml%s,newSize%d write failed\n,newxml,newSize);}}else{Print_WARN(open %s error\n,newxml);}}if(NULL!new_m_fil){int lineSize static_castint(::fwrite(_lineInfo.c_str(), static_castint(sizeof(char)), strlen(_lineInfo.c_str()),new_m_fil));if(lineSize0){Print_WARN(write _lineInfo%s, lineSize%d error\n,_lineInfo.c_str(),lineSize);}}std::string::size_type _posE _lineInfo.find(_xmlEnd);if(std::string::npos ! _posE){if(NULL!new_m_fil){::fclose(new_m_fil);new_m_filNULL;substationIndex1;}}}::fclose(m_fil);m_filNULL;}else{Print_WARN(cont open %s \n,_xmlFile.c_str());m_fil NULL;}
};bool pyfree::createDir(std::string _dir)
{if(isExistDir(_dir))return true;
#ifdef WIN32int ret _mkdir(_dir.c_str());
#elseint ret mkdir(_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
#endifif (-1 ret) {
#ifdef WIN32if (183 ! GetLastError()){Print_WARN(create Directory %s is error,%d \r\n, _dir.c_str(), GetLastError());return false;}
#elseif (EEXIST ! errno) {Print_WARN(create Directory %s is error, %s ! \r\n, _dir.c_str(), strerror(errno));return false;}else{Print_WARN(dir(%s) has exist,dont create it again!\n,_dir.c_str());}
#endif}return true;
};bool pyfree::isExistDir(std::string _dir)
{
#ifdef WIN32if(!_access(_dir.c_str(),0)){return true;}else{// Print_WARN(%s is not exist!\n,_dir.c_str());return false;}
#elseDIR *dfd;if( (dfd opendir(_dir.c_str())) NULL ){return false;}else{return true;}
#endif // WIN32
}bool pyfree::getCurrentDir(char* dir_, int len_)
{char* retNULL;ret getcwd(dir_, len_);return (NULL!ret);
} strchange.cpp
#include strchange.h#include stdio.h
#include stdlib.h
#ifdef __linux__
#include stdio.h
#include stdlib.h
#include string.h
#include iconv.h
#endif
#ifdef WIN32
#include iostream
#include windows.h
#endif
#include vector#ifdef WIN32
//UTF-8 to Unicode
std::wstring pyfree::Utf82Unicode(const std::string utf8string)
{int widesize ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, NULL, 0);if (widesize ERROR_NO_UNICODE_TRANSLATION){throw std::exception(Invalid UTF-8 sequence.);}if (widesize 0){throw std::exception(Error in conversion.);}std::vectorwchar_t resultstring(widesize);int convresult ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, resultstring[0], widesize);if (convresult ! widesize){throw std::exception(La falla!);}return std::wstring(resultstring[0]);
};//unicode to asciistd::string pyfree::WideByte2Acsi(std::wstring wstrcode)
{int asciisize ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, NULL, 0, NULL, NULL);if (asciisize ERROR_NO_UNICODE_TRANSLATION){throw std::exception(Invalid UTF-8 sequence.);}if (asciisize 0){throw std::exception(Error in conversion.);}std::vectorchar resultstring(asciisize);int convresult ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, resultstring[0], asciisize, NULL, NULL);if (convresult ! asciisize){throw std::exception(La falla!);}return std::string(resultstring[0]);
};/////ascii to Unicodestd::wstring pyfree::Acsi2WideByte(std::string strascii)
{int widesize MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);if (widesize ERROR_NO_UNICODE_TRANSLATION){throw std::exception(Invalid UTF-8 sequence.);}if (widesize 0){throw std::exception(Error in conversion.);}std::vectorwchar_t resultstring(widesize);int convresult MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, resultstring[0], widesize);if (convresult ! widesize){throw std::exception(La falla!);}return std::wstring(resultstring[0]);
};//Unicode to Utf8std::string pyfree::Unicode2Utf8(const std::wstring widestring)
{int utf8size ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL);if (utf8size 0){throw std::exception(Error in conversion.);}std::vectorchar resultstring(utf8size);int convresult ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, resultstring[0], utf8size, NULL, NULL);if (convresult ! utf8size){throw std::exception(La falla!);}return std::string(resultstring[0]);
};std::wstring pyfree::stringToWstring(const std::string str)
{LPCSTR pszSrc str.c_str();int nLen MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, NULL, 0);if (nLen 0) return std::wstring(L);wchar_t* pwszDst new wchar_t[nLen];if (!pwszDst) return std::wstring(L);MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, nLen);std::wstring wstr(pwszDst);delete[] pwszDst;pwszDst NULL;return wstr;
}std::string pyfree::wstringToString(const std::wstring wstr)
{LPCWSTR pwszSrc wstr.c_str();int nLen WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);if (nLen 0) return std::string();char* pszDst new char[nLen];if (!pszDst) return std::string();WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);std::string str(pszDst);delete[] pszDst;pszDst NULL;return str;
}#endif#ifdef __linux__
//
int pyfree::code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{iconv_t cd;//int rc;char **pin inbuf;char **pout outbuf;cd iconv_open(to_charset,from_charset);if (cd0) return -1;memset(outbuf,0,outlen);if (-1static_castint(iconv(cd,pin,inlen,pout,outlen)))return -1;iconv_close(cd);return 0;
}
//
int pyfree::u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{char _fbuf[32]utf-8;char _tbuf[32]gb2312;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}
//
int pyfree::g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{char _fbuf[32]gb2312;char _tbuf[32]utf-8;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}int pyfree::u2a(char *inbuf,int inlen,char *outbuf,int outlen)
{char _fbuf[32]utf-8;char _tbuf[32]ascii;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}int pyfree::a2u(char *inbuf,int inlen,char *outbuf,int outlen)
{char _fbuf[32]ascii;char _tbuf[32]utf-8;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}int pyfree::u2k(char *inbuf,int inlen,char *outbuf,int outlen)
{char _fbuf[32]utf-8;char _tbuf[32]gbk;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}int pyfree::k2u(char *inbuf,int inlen,char *outbuf,int outlen)
{char _fbuf[32]gbk;char _tbuf[32]utf-8;return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}#endif//utf-8 to asciistd::string pyfree::UTF_82ASCII(std::string strUtf8Code)
{#ifdef WIN32std::string strRet();//std::wstring wstr Utf82Unicode(strUtf8Code);//strRet WideByte2Acsi(wstr);return strRet;#endif#ifdef __linux__char lpszBuf[1024]{0};u2k(const_castchar*(strUtf8Code.c_str()),strUtf8Code.size(),lpszBuf, 1024);return std::string(lpszBuf);#endif
};//ascii to Utf8std::string pyfree::ASCII2UTF_8(std::string strAsciiCode)
{#ifdef WIN32std::string strRet();//std::wstring wstr Acsi2WideByte(strAsciiCode);//strRet Unicode2Utf8(wstr);return strRet;#endif#ifdef __linux__char lpszBuf[1024]{0};k2u(const_castchar*(strAsciiCode.c_str()),strAsciiCode.size(),lpszBuf, 1024);return std::string(lpszBuf);#endif
};