2021-01-21 11:52:37 +08:00
|
|
|
|
#ifndef HGL_FILESYSTEM_FILENAME_INCLUDE
|
|
|
|
|
#define HGL_FILESYSTEM_FILENAME_INCLUDE
|
|
|
|
|
|
|
|
|
|
#include<hgl/type/StringList.h>
|
2022-05-31 17:21:17 +08:00
|
|
|
|
#include<hgl/math/PrimaryMathematics.h>
|
2021-09-07 13:08:58 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Maximum Path Length Limitation
|
|
|
|
|
* https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
|
2023-07-21 18:29:23 +08:00
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* File name rules
|
|
|
|
|
*
|
|
|
|
|
* Windows
|
|
|
|
|
*
|
|
|
|
|
* + drive_letter
|
|
|
|
|
* | + directory separator
|
|
|
|
|
* | | + filename separator
|
|
|
|
|
* v v v
|
|
|
|
|
* C:\directory\filename.ext
|
|
|
|
|
* ----v---- ---v--- -v-
|
|
|
|
|
* path name ext
|
2021-09-07 13:08:58 +08:00
|
|
|
|
*/
|
|
|
|
|
|
2021-01-21 11:52:37 +08:00
|
|
|
|
namespace hgl
|
|
|
|
|
{
|
|
|
|
|
namespace filesystem
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 组合文件名.<Br>
|
|
|
|
|
* 根据离散的每一级目录名称和最终名称合成完整文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
2021-09-14 09:55:58 +08:00
|
|
|
|
inline const String<T> ComboFilename(T **str_list,int *str_len,const int count,const T spear_char=(T)HGL_DIRECTORY_SEPARATOR_RAWCHAR)
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
|
|
|
|
T *fullname=nullptr;
|
|
|
|
|
|
|
|
|
|
{
|
2021-09-14 09:55:58 +08:00
|
|
|
|
const int total=sum(str_len,count)+count;
|
2021-01-21 11:52:37 +08:00
|
|
|
|
|
2021-09-14 09:55:58 +08:00
|
|
|
|
fullname=new T[total];
|
2021-01-21 11:52:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
T *p=fullname;
|
|
|
|
|
const T *tmp;
|
|
|
|
|
int len;
|
|
|
|
|
bool first=true;
|
|
|
|
|
|
2021-09-07 13:08:58 +08:00
|
|
|
|
for(int i=0;i<count;i++)
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
2021-09-07 13:08:58 +08:00
|
|
|
|
len=str_len[i];
|
2021-01-21 11:52:37 +08:00
|
|
|
|
|
2021-09-07 13:08:58 +08:00
|
|
|
|
if(len<=0)continue;
|
|
|
|
|
|
|
|
|
|
tmp=trim<T>(str_list[i],len,isslash<T>);
|
2021-01-21 11:52:37 +08:00
|
|
|
|
|
|
|
|
|
if(!first)
|
|
|
|
|
{
|
|
|
|
|
*p=spear_char;
|
|
|
|
|
++p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
first=false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hgl_cpy<T>(p,tmp,len);
|
|
|
|
|
p+=len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*p=0;
|
|
|
|
|
|
|
|
|
|
return String<T>::newOf(fullname,p-fullname);
|
|
|
|
|
}
|
2022-03-15 18:01:38 +08:00
|
|
|
|
|
2021-09-07 13:08:58 +08:00
|
|
|
|
/**
|
|
|
|
|
* 组合文件名.<Br>
|
|
|
|
|
* 根据离散的每一级目录名称和最终名称合成完整文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
2021-09-14 09:55:58 +08:00
|
|
|
|
inline const String<T> ComboFilename(T **str_list,const int count,const T spear_char=(T)HGL_DIRECTORY_SEPARATOR_RAWCHAR)
|
2021-09-07 13:08:58 +08:00
|
|
|
|
{
|
|
|
|
|
int str_len[count];
|
|
|
|
|
|
2022-05-31 17:21:17 +08:00
|
|
|
|
for(int i=0;i<count;i++)
|
2021-09-07 13:08:58 +08:00
|
|
|
|
str_len=strlen(str_list[i]);
|
|
|
|
|
|
|
|
|
|
return ComboFilename(str_list,str_len,count,spear_char);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 组合文件名.<Br>
|
|
|
|
|
* 根据离散的每一级目录名称和最终名称合成完整文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
2022-03-31 18:13:36 +08:00
|
|
|
|
inline const String<T> ComboFilename(const StringList<T> &sl,const T spear_char=(T)HGL_DIRECTORY_SEPARATOR_RAWCHAR)
|
2021-09-07 13:08:58 +08:00
|
|
|
|
{
|
2024-07-26 03:13:42 +08:00
|
|
|
|
const int count=sl.GetCount();
|
|
|
|
|
|
|
|
|
|
if(count<=0)
|
|
|
|
|
return String<T>();
|
|
|
|
|
|
|
|
|
|
AutoDeleteArray<T *> str_list(count);
|
|
|
|
|
AutoDeleteArray<int> str_len(count);
|
2021-09-07 13:08:58 +08:00
|
|
|
|
|
|
|
|
|
int index=0;
|
|
|
|
|
|
2024-07-26 03:13:42 +08:00
|
|
|
|
for(String<T> *str:sl)
|
2021-09-07 13:08:58 +08:00
|
|
|
|
{
|
|
|
|
|
if(str->IsEmpty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
str_list[index]=str->c_str();
|
|
|
|
|
str_len[index]=str->Length();
|
|
|
|
|
|
|
|
|
|
++index;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-26 03:13:42 +08:00
|
|
|
|
return ComboFilename(str_list.data(),str_len,count,spear_char);
|
2021-09-07 13:08:58 +08:00
|
|
|
|
}
|
2021-01-21 11:52:37 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 合成文件名<br>
|
|
|
|
|
* 根据路径名和文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> MergeFilename(const String<T> &pathname,const String<T> &filename,const T directory_separator_char,const T *directory_separator_str)
|
|
|
|
|
{
|
|
|
|
|
String<T> fullname;
|
|
|
|
|
|
2022-12-28 17:14:33 +08:00
|
|
|
|
if(pathname.GetLastChar()==directory_separator_char) //结尾有分隔符
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
2022-08-04 10:47:10 +08:00
|
|
|
|
if(filename.GetFirstChar()==directory_separator_char) //开头有分隔符
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
|
|
|
|
fullname.SetString(pathname.c_str(),pathname.Length()-1); //少取一个字符
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fullname=pathname;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else //结尾没有分隔符
|
|
|
|
|
{
|
|
|
|
|
fullname=pathname;
|
|
|
|
|
|
2022-08-04 10:47:10 +08:00
|
|
|
|
if(filename.GetFirstChar()!=directory_separator_char) //开头没有分隔符
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
|
|
|
|
fullname.Strcat(directory_separator_str); //添加分隔符
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fullname.Strcat(filename);
|
|
|
|
|
return fullname;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 截取完整路径中的文件名
|
|
|
|
|
* @param fullname 完整路径文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ClipFilename(const String<T> &fullname)
|
|
|
|
|
{
|
|
|
|
|
if(fullname.Length()<=1)
|
|
|
|
|
return(String<T>());
|
|
|
|
|
|
|
|
|
|
const T spear_char[] = { '/','\\',0 };
|
|
|
|
|
|
|
|
|
|
const int pos=fullname.FindRightChars(spear_char);
|
|
|
|
|
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return String<T>(fullname);
|
|
|
|
|
|
|
|
|
|
return fullname.SubString(pos+1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 截取一个文件名中的主名称
|
|
|
|
|
* @param filename 文件名
|
|
|
|
|
* @param split_char 扩展名分隔符,一般为'.'
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ClipFileMainname(const String<T> &filename,const T split_char='.')
|
|
|
|
|
{
|
|
|
|
|
if(filename.Length()<=1)
|
|
|
|
|
return(String<T>());
|
|
|
|
|
|
|
|
|
|
const T spear_char[] = { '/','\\',0 };
|
|
|
|
|
|
|
|
|
|
const int dot=filename.FindRightChar(split_char);
|
|
|
|
|
const int pos=filename.FindRightChars(spear_char);
|
|
|
|
|
|
|
|
|
|
if(dot==-1)
|
|
|
|
|
{
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return String<T>(filename);
|
|
|
|
|
else
|
|
|
|
|
return filename.SubString(pos+1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return filename.SubString(0,dot);
|
|
|
|
|
else
|
|
|
|
|
return filename.SubString(pos+1,dot-pos-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 截取完整文件名中的扩展名
|
|
|
|
|
* @param fullname 完整文件名
|
|
|
|
|
* @param include_dot 是否包括点
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ClipFileExtName(const String<T> &fullname,bool include_dot=true)
|
|
|
|
|
{
|
|
|
|
|
int end=fullname.FindChar(T('?')); //url的文件名,以?为结束
|
|
|
|
|
|
|
|
|
|
if(end==-1)
|
|
|
|
|
end=fullname.Length();
|
|
|
|
|
|
|
|
|
|
int pos=fullname.FindRightChar(fullname.Length()-end,T('.'));
|
|
|
|
|
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return String<T>();
|
|
|
|
|
|
|
|
|
|
return include_dot? fullname.SubString(pos, end- pos ):
|
|
|
|
|
fullname.SubString(pos+1, end-(pos+1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 清除完整文件名中的扩展名
|
|
|
|
|
* @param fullname 完整文件名
|
2021-12-13 13:40:32 +08:00
|
|
|
|
* @param clear_dot 是否包括点也清除
|
2021-01-21 11:52:37 +08:00
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
2021-12-13 13:40:32 +08:00
|
|
|
|
inline String<T> TrimFileExtName(const String<T> &fullname,bool clear_dot=false)
|
2021-01-21 11:52:37 +08:00
|
|
|
|
{
|
|
|
|
|
int end=fullname.FindChar(T('?')); //url的文件名,以?为结束
|
|
|
|
|
|
|
|
|
|
if(end==-1)
|
|
|
|
|
end=fullname.Length();
|
|
|
|
|
|
|
|
|
|
int pos=fullname.FindRightChar(fullname.Length()-end,T('.'));
|
|
|
|
|
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return String<T>();
|
|
|
|
|
|
2021-12-13 13:40:32 +08:00
|
|
|
|
return clear_dot? fullname.SubString(0,pos):
|
2021-01-21 11:52:37 +08:00
|
|
|
|
fullname.SubString(0,pos+1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 截取一个文件名中的路径名
|
|
|
|
|
* @param filename 文件名
|
|
|
|
|
* @param include_spear_char 是否包含最后的分隔符
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ClipPathname(const String<T> &filename,bool include_spear_char=true)
|
|
|
|
|
{
|
|
|
|
|
if(filename.Length()<=1)
|
|
|
|
|
return(String<T>());
|
|
|
|
|
|
|
|
|
|
const T spear_char[] = { '/','\\',':',0};
|
|
|
|
|
|
|
|
|
|
const int pos=filename.FindRightChars(spear_char);
|
|
|
|
|
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return filename;
|
|
|
|
|
else
|
|
|
|
|
if(include_spear_char)
|
2023-01-10 17:23:00 +08:00
|
|
|
|
return filename.SubString(0,pos+1);
|
2021-01-21 11:52:37 +08:00
|
|
|
|
else
|
2023-01-10 17:23:00 +08:00
|
|
|
|
return filename.SubString(0,pos);
|
2021-01-21 11:52:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 截取路径最后一个名字
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ClipLastPathname(const String<T> &fullname)
|
|
|
|
|
{
|
|
|
|
|
if(fullname.Length()<=1)
|
|
|
|
|
return(String<T>());
|
|
|
|
|
|
|
|
|
|
const T gap_char[]={'\\','/',0};
|
|
|
|
|
|
|
|
|
|
T *p=nullptr;
|
|
|
|
|
|
|
|
|
|
T *s=fullname.c_str();
|
|
|
|
|
T *e=fullname.c_str()+fullname.Length()-1;
|
|
|
|
|
|
|
|
|
|
while(e>s)
|
|
|
|
|
{
|
|
|
|
|
if(!p)
|
|
|
|
|
{
|
|
|
|
|
if(*e==gap_char[0]||*e==gap_char[1])
|
|
|
|
|
{
|
|
|
|
|
--e;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p=e;
|
|
|
|
|
--e;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(*e==gap_char[0]||*e==gap_char[1])
|
|
|
|
|
{
|
|
|
|
|
return String<T>(e+1,p-e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(String<T>());
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 13:40:32 +08:00
|
|
|
|
/**
|
|
|
|
|
* 截取完整路径中的路径名和文件名
|
|
|
|
|
* @param pathname 拆分后的路径名
|
|
|
|
|
* @param filename 拆分后的文件名
|
|
|
|
|
* @param fullname 拆分前的完整路径文件名
|
|
|
|
|
*/
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline bool SplitFilename(String<T> &pathname,String<T> &filename,const String<T> &fullname)
|
|
|
|
|
{
|
|
|
|
|
if(fullname.Length()<=1)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
const T spear_char[] = { '/','\\' };
|
|
|
|
|
|
|
|
|
|
const int pos=fullname.FindRightChars(spear_char);
|
|
|
|
|
|
|
|
|
|
if(pos==-1)
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
pathname.Strcpy(fullname,pos);
|
|
|
|
|
filename.Strcpy(fullname.c_str()+pos+1);
|
|
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline String<T> ReplaceExtName(const String<T> &old_name,const String<T> &new_extname,const T split_char='.')
|
|
|
|
|
{
|
|
|
|
|
if(old_name.Length()<=1)
|
|
|
|
|
return(String<T>::charOf(split_char)+new_extname);
|
|
|
|
|
|
|
|
|
|
const int pos=old_name.FindRightChar(split_char);
|
|
|
|
|
|
|
|
|
|
if(pos!=-1)
|
|
|
|
|
return old_name.SubString(0,pos)+new_extname;
|
|
|
|
|
else
|
|
|
|
|
return old_name+String<T>::charOf(split_char)+new_extname;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-26 03:13:42 +08:00
|
|
|
|
#ifdef HGL_SUPPORT_CHAR8_T
|
|
|
|
|
inline AnsiString MergeFilename(const AnsiString &pathname,const AnsiString &filename) ///<组合路径名与文件名
|
|
|
|
|
{return MergeFilename<char>(pathname,filename,HGL_DIRECTORY_SEPARATOR,HGL_DIRECTORY_SEPARATOR_RAWSTR);}
|
|
|
|
|
#endif//HGL_SUPPORT_CHAR8_T
|
|
|
|
|
|
2021-01-21 11:52:37 +08:00
|
|
|
|
inline UTF8String MergeFilename(const UTF8String &pathname,const UTF8String &filename) ///<组合路径名与文件名
|
|
|
|
|
{return MergeFilename<u8char>(pathname,filename,HGL_DIRECTORY_SEPARATOR,HGL_DIRECTORY_SEPARATOR_U8STR);}
|
|
|
|
|
|
2022-12-28 17:14:33 +08:00
|
|
|
|
#if HGL_OS == HGL_OS_Windows
|
2021-01-21 11:52:37 +08:00
|
|
|
|
inline WideString MergeFilename(const WideString &pathname,const WideString &filename) ///<组合路径名与文件名
|
|
|
|
|
{return MergeFilename<wchar_t>(pathname,filename,L'\\',L"\\");}
|
2022-12-28 17:14:33 +08:00
|
|
|
|
#endif//HGL_OS == HGL_OS_Windows
|
2021-09-04 13:44:24 +08:00
|
|
|
|
|
|
|
|
|
OSString FixFilename(const OSString &filename); ///<修正部分文件名问题
|
2021-01-21 11:52:37 +08:00
|
|
|
|
}//namespace filesystem
|
|
|
|
|
}//namespace hgl
|
|
|
|
|
#endif//HGL_FILESYSTEM_FILENAME_INCLUDE
|