CMCore/src/FileSystem/FileSystem.cpp

451 lines
12 KiB
C++
Raw Normal View History

2019-08-19 19:19:58 +08:00
#include <hgl/filesystem/FileSystem.h>
2019-08-27 20:26:44 +08:00
#include <hgl/log/LogInfo.h>
2019-08-19 19:19:58 +08:00
#include <hgl/io/FileInputStream.h>
#include <hgl/io/FileOutputStream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
namespace hgl
{
namespace filesystem
{
/**
* ()
*/
OSString FixFilename(const OSString &filename)
{
int old_len=filename.Length();
int new_len;
os_char *new_string=new os_char[old_len+1];
os_char *sp=filename.c_str();
os_char *tp=new_string;
os_char last_char=0;
bool fix=false;
while(*sp)
{
if(*sp==HGL_INCORRECT_DIRECTORY_SEPARATOR)
{
if(last_char==HGL_INCORRECT_DIRECTORY_SEPARATOR)
{
fix=true;
++sp;
continue;
}
else
{
last_char=*sp;
fix=true;
++sp;
*tp=HGL_DIRECTORY_SEPARATOR;
}
}
else
{
if(*sp==HGL_DIRECTORY_SEPARATOR
&&last_char==HGL_DIRECTORY_SEPARATOR)
{
last_char=*sp;
fix=true;
++sp;
continue;
}
else
{
last_char=*sp;
*tp=*sp;
++sp;
}
}
++tp;
}
*tp=0;
new_len=tp-new_string;
if(!fix)
{
delete[] new_string;
return filename;
}
return OSString::newOf(new_string,new_len);
}
2019-08-19 19:19:58 +08:00
/**
*
* @param filename1
* @param filename2
2020-05-06 17:13:16 +08:00
* @param buf_size
2019-08-19 19:19:58 +08:00
* @return
*/
2020-05-06 17:13:16 +08:00
bool FileComp(const OSString &filename1,const OSString &filename2,const size_t buf_size)
2019-08-19 19:19:58 +08:00
{
io::FileInputStream fp1,fp2;
int64 fs1,fs2;
if(!fp1.Open(filename1))return(false);
if(!fp2.Open(filename2))return(false);
fs1=fp1.GetSize();
fs2=fp2.GetSize();
if(fs1!=fs2)
return(false);
int64 pos=0,size;
AutoDeleteArray<char> data1(buf_size);
AutoDeleteArray<char> data2(buf_size);
2019-08-19 19:19:58 +08:00
while(pos<fs1)
{
2020-05-06 17:13:16 +08:00
size=buf_size;
2019-08-19 19:19:58 +08:00
if(pos+size>fs1)size=fs1-pos;
fp1.Read(data1,size);
fp2.Read(data2,size);
2020-05-06 17:13:16 +08:00
if(memcmp(data1,data2,size))
2019-08-19 19:19:58 +08:00
return(false);
2020-05-06 17:13:16 +08:00
pos+=size;
}
2019-08-19 19:19:58 +08:00
return(true);
}
void *LoadFileToMemory(const OSString &filename,int64 &size,bool append_zero)
2019-08-19 19:19:58 +08:00
{
io::FileInputStream fs;
if(!fs.Open(filename))
return(nullptr);
2019-08-19 19:19:58 +08:00
size=fs.GetSize();
2019-08-19 19:19:58 +08:00
char *fb=new char[append_zero?size+1:size];
2019-08-19 19:19:58 +08:00
if(fs.Read(fb,size)==size)
{
if(append_zero)
fb[size]=0;
return fb;
2019-08-19 19:19:58 +08:00
}
delete[] fb;
return(nullptr);
}
/**
* ,delete[]
* @param filename
* @param buf
* @return
*/
int64 LoadFileToMemory(const OSString &filename,void **buf,bool append_zero)
{
int64 size;
*buf=LoadFileToMemory(filename,size,append_zero);
return size;
2019-08-19 19:19:58 +08:00
}
/**
*
* @param filename
* @param buf
* @param size
* @return
* @return -1
*/
int64 SaveMemoryToFile(const OSString &filename,const void *buf,const int64 &size)
{
io::FileOutputStream fs;
if(!fs.CreateTrunc(filename))
return(-1);
return fs.Write(buf,size);
}
/**
*
* @param filename
* @param buf_list
* @param buf_size
* @param buf_count
* @return
* @return -1
*/
int64 SaveMemoryToFile(const OSString &filename,void **buf_list,const int64 *buf_size,const int &buf_count)
{
io::FileOutputStream fs;
if(!fs.CreateTrunc(filename))
return(-1);
int64 total=0;
int64 result;
for(int i=0;i<buf_count;i++)
{
result=fs.Write(buf_list[i],buf_size[i]);
if(result!=buf_size[i])
return -1;
total+=result;
}
return total;
}
os_char *GetRootPath(os_char *str);
bool MakeDirectory(const os_char *name);
/**
* ,
* @param dirname
* @return
*/
bool MakePath(const OSString &dirname)
{
constexpr os_char directory_separator=HGL_DIRECTORY_SEPARATOR;
os_char *p;
os_char str[HGL_MAX_PATH];
os_char *sp;
FileInfo fi;
strcpy(str,HGL_MAX_PATH,dirname.c_str());
sp=GetRootPath(str);
while(1)
{
p=hgl::strchr(sp,directory_separator);
if(p)
*p=0;
if(*sp==0)
return(true);
if(!GetFileInfo(str,fi)) //没有找到
{
if(!MakeDirectory(str))
return(false);
}
else
{
if(!fi.is_directory) //不是目录
#if HGL_OS != HGL_OS_Windows
if(!fi.is_link) //还不是链接
#endif//HGL_OS != HGL_OS_Windows
return(false);
}
if(p)
*p++=directory_separator;
else
return(true);
while(*p==directory_separator) //跳过那种连续的分隔符,比如C:\\Windows
++p;
sp=p;
}
}
/**
* ,
* @param dirname
* @return
*/
// void DeleteTree(const OSString &dirname)
// {
// }
/**
*
* @param filename
* @param offset
* @param length
* @param buf ,NULL表示要求函数分配
* @return NULL
* @return
*/
void *LoadFileToMemory(const OSString &filename,int64 offset,void *buf,int64 length)
{
if(!filename||!*filename||length==0)
return(nullptr);
io::FileInputStream fs;
if(!fs.Open(filename))
return(nullptr);
const int64 file_length=fs.GetSize();
if(offset+length>file_length)
{
2020-04-24 21:09:25 +08:00
LOG_PROBLEM(OS_TEXT("读取文件<")+filename+OS_TEXT("><")+OSString::valueOf(offset)+OS_TEXT(",")+OSString::valueOf(length)+OS_TEXT(">超出了范围,文件长度为<")+OSString::valueOf(file_length));
2019-08-19 19:19:58 +08:00
return(nullptr);
}
char *fb;
if(buf)
fb=(char *)buf;
else
fb=new char[length];
if(fs.Read(offset,fb,length)==length)
{
2020-04-24 21:09:25 +08:00
LOG_INFO(OS_TEXT("加载文件<")+filename+OS_TEXT("><")+OSString::valueOf(offset)+OS_TEXT(",")+OSString::valueOf(length)+OS_TEXT(">到缓冲区成功."));
2019-08-19 19:19:58 +08:00
return(buf);
}
else
{
if(fb!=buf)
delete[] fb;
return(nullptr);
}
}
/**
*
* @param filename
* @param offset
* @param length
* @param data
* @return
*/
bool SaveMemoryToFile(const OSString &filename,int64 offset,const void *data,int64 length)
{
io::FileOutputStream fs;
if(!fs.Open(filename))
return(false);
return fs.Write(offset,data,length);
}
bool GetFileInfo(const os_char *filename,struct FileInfo &fi)
{
if(!filename||!*filename)
return(false);
struct_stat64 file_state;
2020-05-06 17:13:16 +08:00
hgl_zero(file_state);
2019-08-19 19:19:58 +08:00
if(hgl_lstat64(filename,&file_state)==-1)
return(false);
2020-05-06 17:13:16 +08:00
hgl_zero(fi);
2019-08-19 19:19:58 +08:00
if(file_state.st_mode&S_IFREG)
fi.is_file=true;
if(file_state.st_mode&S_IFDIR)
fi.is_directory=true;
if (file_state.st_mode&S_IREAD)
fi.can_read = true;
if (file_state.st_mode&S_IWRITE)
fi.can_write = true;
#if HGL_OS != HGL_OS_Windows
if(file_state.st_mode&S_IFLNK)
fi.is_link=true;
#endif//HGL_OS != HGL_OS_Windows
fi.size=file_state.st_size;
return(true);
}
/**
*
* @param filename
* @param paths
* @param user_data
* @param ff
*/
const uint FindFileOnPaths(const OSString &filename,const OSStringList &paths,void *user_data,OnFindedFileFUNC ff)
{
if(filename.IsEmpty()||paths.GetCount()<=0)return(0);
if(ff==nullptr)return 0;
uint count=0;
bool exist;
OSString full_filename;
for(const OSString *pn:paths)
{
full_filename=MergeFilename(*pn,filename);
exist=FileExist(full_filename);
if(exist)
++count;
if(!ff(full_filename,user_data,exist))
return(count);
}
return count;
}
/**
*
* @param filenames
* @param paths
* @param user_data
* @param ff
*/
const uint FindFileOnPaths(const OSStringList &filenames,const OSStringList &paths,void *user_data,OnFindedFileFUNC ff)
{
if(filenames.GetCount()<=0||paths.GetCount()<=0)return(0);
if(ff==nullptr)return 0;
uint count=0;
bool exist;
OSString full_filename;
for(const OSString *pn:paths)
{
for(const OSString *fn:filenames)
{
full_filename=MergeFilename(*pn,*fn);
exist=FileExist(full_filename);
if(exist)
++count;
if(!ff(full_filename,user_data,exist))
return(count);
}
}
return count;
}
2019-08-19 19:19:58 +08:00
}//namespace filesystem
}//namespace hgl