一、緩存檔案系統
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::vector<std::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::vector<std::vector<std::string> > &list,const std::string path);//讀取多行内容
bool readListInfo(std::vector<std::vector<std::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_cast<int>(sizeof(char)), (size_t)buf_size,m_fil);
//寫入
::fwrite(buf, static_cast<int>(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::vector<std::string> _lineList; // Create vector to hold our words
while(_lineStr >> buffer)
{
_lineList.push_back(buffer);
}
//将采用","間隔的字元串劃分成子字元串集
void pyfree::getNumberFromStr(std::vector<std::string> &ids, std::string idsStr)
{
if(""==idsStr||"NULL"==idsStr)
return;
std::string id = "";
for(unsigned int i=0,idSize= static_cast<unsigned int>(idsStr.size()); i<idSize; 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::vector<std::vector<std::string> > &list,const std::string path,int codef=0);//讀取多行内容
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);//讀取多行内容,每行按空格分割
2.2 工程及代碼設計
建立項目目錄結構如下:
myfile_test
bin
build_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.h>
namespace 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::vector<std::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 {vector<vector>} 讀取内容容器,每一行作為一項載入容器,每行内容分割後容器裝載
* @param path {string} 檔案名
* @param codef {int} 讀取時編碼轉換{1:g2u,2:a2u,其他不做處理}
* @return {bool}
*/
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);
/**
* 從指定檔案中讀取檔案每一行的字元串,如果行中存在","間隔,劃分該行字元串,并裝在到容器中
* @param list {vector<vector>} 讀取内容容器,每一行作為一項載入容器,每行内容分割後容器裝載
* @param path {string} 檔案名
* @param codef {int} 讀取時編碼轉換{1:g2u,2:a2u,其他不做處理}
* @return {bool}
*/
bool readListInfo_dot(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);
/**
* 從指定檔案中讀取檔案每一行的字元串并裝在到容器中
* @param list {vector} 讀取内容容器,每一行作為一項載入容器
* @param path {string} 檔案名
* @param codef {int} 讀取時編碼轉換{1:g2u,2:a2u,其他不做處理}
* @return {bool}
*/
bool readListInfo(std::vector<std::string> &list,const std::string path,int codef=0);
/**
* 将采用","間隔的字元串劃分成子字元串集,被readListInfo_dot調用
* @param ids {vector} 讀取内容容器
* @param idsStr {string} 被檢查字元串
* @return {void}
*/
void getNumberFromStr(std::vector<std::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::vector<std::string>& fileNames);
/**
* 從指定檔案目錄下讀取指定擴充名的檔案名,傳回結果不包含擴充名
* @param directory {string} 檔案目錄
* @param extName {string} 擴充名
* @param fileNames {vector} 讀取結果
* @return {bool} 是否成功
*/
void getAllFileName(const std::string& directory, const std::string& extName, std::vector<std::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::vector<std::string>& fileNames
, bool f=false);
/**
* 讀取檔案修改時間
* @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 <functional>
namespace 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 NULL
if(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 <string>
namespace 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, //軟體bug
LL_FATAL = 5 //緻命錯誤
}PrintLevel;
#define Print_NOTICE(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_NOTICE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_WARN(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_WARNING, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_TRACE(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_TRACE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_DEBUG(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_DEBUG, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_FATAL(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n",LL_FATAL, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#endif
在test目錄下,建立main.cpp,File IO子產品調用示例程式
#include "File.h"
#include "pfunc_print.h"
int 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::vector<std::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_name
if(!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::vector<std::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 i=0; i<list.size(); i++){
printf("row[%u]:%s\n",i,list.at(i).c_str());
}
}
//空格間隔測試
std::vector<std::vector<std::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 i=0; i<lists.size(); i++)
{
for(unsigned int j=0; j<lists.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 i=0; i<lists.size(); i++)
{
for(unsigned int j=0; j<lists.at(i).size(); j++){
printf("row[%u] col[%u]:%s",i,j,lists.at(i).at(j).c_str());
}
printf("\n");
}
}
std::vector<std::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 i=0; i<fileNames.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 i=0; i<fileNames.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 i=0; i<list.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 i=0; i<list.size(); i++){
printf("row[%u]:%s\n",i,list.at(i).c_str());
}
}
return 0;
}
2.3 編譯及測試
完成後,項目檔案結構如下:
myfile_test
bin
build_win //win編譯過程檔案路徑
build_linux //Linux編譯過程檔案目錄
src //檔案接口源碼
File.h
File.cpp
pfunc_print.h
strTrim.h
strchange.h
strchange.cpp
test //接口調用示例
main.cpp
CMakeLists.txt //cmake工程配置檔案
編譯指令.txt //編輯及運作指令
CMakeLists.txt内容如下,基于cmake+vs(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_TYPE=Release .. -Wno-dev
#vs 指令視窗
msbuild file_test.sln /p:Configuration="Release" /p:Platform="x64"
linux:
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.h"
bool 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_cast<int>(sizeof(char)), strlen(ptr),m_fil);
::fclose(m_fil);
m_fil = NULL;
if(size>0)
{
return true;
}else{
return false;
}
}
else{
m_fil = NULL;
return false;
}
}
bool pyfree::writeListInfo(std::vector<std::string> list,const std::string path)
{
size_t newSize = 0;
FILE *new_m_fil=NULL;
new_m_fil = ::fopen(path.c_str(),"a+");
if(NULL!=new_m_fil)
{
for(size_t i=0,lSize=list.size(); i<lSize; i++)
{
newSize += ::fwrite(list.at(i).c_str(), static_cast<int>(sizeof(char)), strlen(list.at(i).c_str()),new_m_fil);
}
::fclose(new_m_fil);
}
new_m_fil = NULL;
if(newSize>0){
return true;
}
return false;
}
bool pyfree::readFromFile(char *ptr, int &size, int buf_size,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 = static_cast<int>( ::fread(ptr, static_cast<int>(sizeof(char)), (size_t)buf_size,m_fil) );
::fclose(m_fil);
m_fil = NULL;
if(size>0)
{
return true;
}else
return false;
}else{
m_fil = NULL;
return false;
}
}
//讀取檔案每一行得字元串,如果行中存在空格,劃分該行字元串,并裝在到容器中
bool pyfree::readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef)
{
FILE *m_fil=NULL;
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;
}
#endif
std::string buffer;// Have a buffer string
std::stringstream _lineStr(_lineInfo);// Insert the string into a stream
std::vector<std::string> _lineList;// Create vector to hold our words
while(_lineStr >> buffer)
{
_lineList.push_back(buffer);
}
list.push_back(_lineList);
}
::fclose(m_fil);
m_fil = NULL;
if(list.empty()){
return false;
}
}else{
#ifdef WIN32
Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
#endif
#ifdef linux
Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
#endif
m_fil = NULL;
return false;
}
return true;
}
//将采用","間隔的字元串劃分成子字元串集
void pyfree::getNumberFromStr(std::vector<std::string> &ids, std::string idsStr)
{
if(""==idsStr||"NULL"==idsStr)
return;
std::string id = "";
for(unsigned int i=0,idSize= static_cast<unsigned int>(idsStr.size()); i<idSize; 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::vector<std::vector<std::string> > &list,const std::string path,int codef)
{
FILE *m_fil=NULL;
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;
}
#endif
std::vector<std::string> _lineList;
getNumberFromStr(_lineList,_lineInfo);
list.push_back(_lineList);
}
::fclose(m_fil);
m_fil = NULL;
if(list.empty()){
return false;
}
}else{
#ifdef WIN32
Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
#endif
#ifdef linux
Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
#endif
m_fil = NULL;
return false;
}
return true;
}
//讀取檔案,并将每一行字元串載入容器
bool pyfree::readListInfo(std::vector<std::string> &list,const std::string path,int codef)
{
FILE *m_fil=NULL;
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;
}
#endif
list.push_back(_lineInfo);
}
::fclose(m_fil);
m_fil = NULL;
if(list.empty()){
return false;
}
}else{
#ifdef WIN32
Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
#endif
#ifdef linux
Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
#endif
m_fil = NULL;
return false;
}
return true;
}
//獲得dire目錄下擴充名為extName的所有檔案名
void pyfree::getAllFileName_dot(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames)
{
getAllFileNamePrivate(directory,extName,fileNames,true);
}
//獲得dire目錄下擴充名為extName的所有檔案名
void pyfree::getAllFileName(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames)
{
getAllFileNamePrivate(directory,extName,fileNames);
}
void pyfree::getAllFileNamePrivate(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames,bool f)
{
#ifdef WIN32
_finddata_t fileInfo;
intptr_t hFile;
std::string filter = directory;
char bch = static_cast<char>(('//') & 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 (0==strcmp(fileInfo.name,".") || 0==strcmp(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 linux
std::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 ( 0==strcmp(dp->d_name, ".") || 0==strcmp(dp->d_name, "..") )
{
continue;
}
fileNames.push_back(dp->d_name);
}
}else{
if ( NULL==strstr(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_cast<unsigned 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(0==stat(file_path.c_str(), &el))
{
ret = static_cast<unsigned int>(el.st_mtime);
}else{
Print_WARN("get file %s last modify time error: %s\n"
,file_path.c_str(),strerror(errno));
}
#else
ret = 0;
#endif // WIN32
return 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("can't 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 linux
FILE* m_fil = ::fopen(_oldName.c_str(),"r");
if(NULL==m_fil){
return;
}
::fclose(m_fil);
m_fil = NULL;
#endif
Print_NOTICE("%s, %s\n", _oldName.c_str(),_newName.c_str());
int ret = rename(_oldName.c_str(),_newName.c_str());
if(0 != ret)
{
Print_WARN("can't 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("can't 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;
#else
FILE *m_fil=NULL;
m_fil=::fopen(file.c_str(),"rb");
if(NULL==m_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 WIN32
path+="\\";
#else
path+="/";
#endif
path+=file;
return isExist(path);
};
void pyfree::divXmlFile(std::string _xmlFile,std::string _xmlDir,std::string _xmlDiv,bool utfFlag)
{
static int substationIndex = 1;
FILE *m_fil=NULL;
FILE *new_m_fil=NULL;
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_fil=fopen(_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_cast<int>(::fwrite(_xmlNode.c_str(), static_cast<int>(sizeof(char)), strlen(_xmlNode.c_str()),new_m_fil));
if(newSize<=0)
{
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_cast<int>(::fwrite(_lineInfo.c_str(), static_cast<int>(sizeof(char)), strlen(_lineInfo.c_str()),new_m_fil));
if(lineSize<=0){
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_fil=NULL;
substationIndex+=1;
}
}
}
::fclose(m_fil);
m_fil=NULL;
}else{
Print_WARN("con't open %s \n",_xmlFile.c_str());
m_fil = NULL;
}
};
bool pyfree::createDir(std::string _dir)
{
if(isExistDir(_dir))
return true;
#ifdef WIN32
int ret = _mkdir(_dir.c_str());
#else
int ret = mkdir(_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
#endif
if (-1 == ret) {
#ifdef WIN32
if (183 != GetLastError())
{
Print_WARN("create Directory %s is error,%d \r\n", _dir.c_str(), GetLastError());
return false;
}
#else
if (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,don't create it again!\n",_dir.c_str());
}
#endif
}
return true;
};
bool pyfree::isExistDir(std::string _dir)
{
#ifdef WIN32
if(!_access(_dir.c_str(),0))
{
return true;
}
else
{
// Print_WARN("%s is not exist!\n",_dir.c_str());
return false;
}
#else
DIR *dfd;
if( (dfd = opendir(_dir.c_str())) == NULL )
{
return false;
}else{
return true;
}
#endif // WIN32
}
bool pyfree::getCurrentDir(char* dir_, int len_)
{
char* ret=NULL;
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::vector<wchar_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 ascii
std::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::vector<char> 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 Unicode
std::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::vector<wchar_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 Utf8
std::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::vector<char> 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 (cd==0) return -1;
memset(outbuf,0,outlen);
if (-1==static_cast<int>(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 ascii
std::string pyfree::UTF_82ASCII(std::string& strUtf8Code)
{
#ifdef WIN32
std::string strRet("");
//
std::wstring wstr = Utf82Unicode(strUtf8Code);
//
strRet = WideByte2Acsi(wstr);
return strRet;
#endif
#ifdef __linux__
char lpszBuf[1024]={0};
u2k(const_cast<char*>(strUtf8Code.c_str()),strUtf8Code.size(),lpszBuf, 1024);
return std::string(lpszBuf);
#endif
};
//ascii to Utf8
std::string pyfree::ASCII2UTF_8(std::string& strAsciiCode)
{
#ifdef WIN32
std::string strRet("");
//
std::wstring wstr = Acsi2WideByte(strAsciiCode);
//
strRet = Unicode2Utf8(wstr);
return strRet;
#endif
#ifdef __linux__
char lpszBuf[1024]={0};
k2u(const_cast<char*>(strAsciiCode.c_str()),strAsciiCode.size(),lpszBuf, 1024);
return std::string(lpszBuf);
#endif
};