CPPFS - 支持多个后端结束的CPPFS - 跨平台C ++文件系统库

2021-03-20 23:36:30

CPPFS是一个跨平台C ++库,提供面向对象的抽象,用于处理文件和文件系统。

CPPF不仅可以访问本地文件系统,而且可以用于远程和虚拟文件系统。专门化虚拟后端接口,可以轻松扩展到CPPF以支持其他remote协议或虚拟文件系统。目前已实现以下后端:

#包括< cppfs / fs.h>#包括< cppfs / filehandle.h>使用命名空间cppfs; void Openfile(const std :: string&文件名){filehandle fh = fs ::打开(文件名); if(fh。isfile()){/ *文件... * /} else if(fh。isdirectory()){/ *目录... * /} else else(!fh。存在()){/ *不在那里 ... */ }}

#包括< cppfs / fs.h>#包括< cppfs / filehandle.h>使用命名空间cppfs; void Openfile(const std :: string&文件名){filehandle fh = fs ::打开(文件名); if(fh。iSfile()){auto in = fh。 createInputStream(); // ...自动= fh。 createOutputStream(); // ...}}

#包括< cppfs / fs.h>#包括< cppfs / filehandle.h>使用命名空间cppfs; void lstdir(const std :: string& path){filehandle dir = fs ::打开(路径); if(dir。isdirectory()){for(fileiterator它= dir。begin();它!= dir。ext。结束(); ++它){std :: string path = *它; }}}

类FilePath用于表示文件系统中的路径。可以从字符串构造并将其转换回字符串。

仅使用正斜杠(' /&#39)作为分隔符以统一格式存储路径。统一格式与所有系统兼容,但作为用户的便利性,在显示路径时应转换为下列格式。将路径转换为NativeFormat,调用调用。

FilePath可用于获取有关路径的语法信息。但是,它纯粹在字符串上工作,它不能提供Path点的实际文件或目录的信息。以下功能可用于获取有关路径的信息:

filepath路径= ...; //检查路径是否为空("")bool空= path.isusempty(); //检查路径是否是绝对路径(例如," /test.txt&"或" c:/ test.txt& n34;)bool abs = path.isabsolute(); //检查路径是否是相对路径(例如,"数据/ test.txt")bool rel = path.isrelative(); //检查path是否指向文件/目录(例如," / path / to / dir")//或其内容(例如," / path / dir / dir / dir / dir / dir / dir / dir / dir /&#34 ;)。 bool listcontent = path.pointstocontent();

filepath提供了获取文件路径的各个组件的函数,例如包含目录的文件名,扩展名或路径。这些函数的所有功能忽略路径上的尾随斜线,因此它们在路径指向的对象上运行,而不是它内容。

filepath path1(&#34; c:/path/to/file.txt&#34;); filepath path2(&#34; c:/ path / to / directory / diguration /&#34;); //获取完整路径:: cout&lt;&lt; path1.fullpath()&lt;&lt; std :: endl; //&#34; c:/path/to/file.txt" std :: cout&lt;&lt; path2.fullpath()&lt;&lt; std :: endl; //&#34; c:/ path / to / directory&#34; //获取文件名componentstd :: cout <&lt;&lt; path1.filename()&lt;&lt; std :: endl; //&#34; file.txt&#34; std :: cout&lt;&lt;&lt; path2.filename()&lt;&lt; std :: endl; //&#34;目录&#34; std :: cout&lt;&lt; path1.baseName()&lt;&lt; std :: endl; //&#34;文件&#34; std :: cout&lt;&lt; path2.baseName()&lt;&lt; std :: endl; //&#34;目录&#34; std :: cout&lt;&lt; path1.extension()&lt;&lt; std :: endl; //&#34; .txt&#34; std :: cout&lt;&lt; path2.extension()&lt;&lt; std :: endl; //#34;&#34; //获得包含directorystd :: cout&lt;&lt;&lt; path1.directoryPath()&lt;&lt; std :: endl; //&#34; c:/ path / to /&#34; std :: cout&lt;&lt; path2.directoryPath()&lt;&lt; std :: endl; //&#34; c:/ path / to /&#34; //获取驱动器Lettertry :: Cout&lt;&lt; path1.driveletter()&lt;&lt; std :: endl; //&#34; c:&#34; std :: cout&lt;&lt; path2.driveletter()&lt;&lt; std :: endl; //&#34; c:&#34;

通常需要组合路径才能确定文件的实际位置。要组合两个路径,可以使用函数解析。第一个路径必须相对于组合两条路径,否则仅返回第一个路径。路径的组合也发生在纯语法级别,而不检查是否存在任何路径。

FIREPATH SRC(&#34; c:/ projects&#34;); filepath rel(&#34; ./文件/ test.txt&#34;); filepath asb(&#34; c:/ projects2 / Readme.txt&#34;); filepath path1 = src.resolve(rel); std :: cout

结合相对路径时,产生的字符串可以包含Lotof&#34; ..&#34;和#34;&#34;成分。要在语法级别解决这些问题,可以调用解决的功能。它将删除所有&#34;。&#34;和&#34;和#34;,只要它是可能的。 &#34; ..&#34;在一开始就不会删除路径。

用于访问CPPFS中的文件和目录的主类是FileHandle.it可用于将有关文件系统对象的信息,用于Manipulatethem(例如,复制,重命名或删除),以及读写文件。

要获取文件句柄,可以调用全局函数fs ::打开。访问的TheType将由可访问的路径或URL自动确定。文件系统将在剩余的任何打开文件处理时自动关闭。

//打开本地FileFileHandle File1 = FS :: Open(&#34;数据/ Readme.txt&#34;); //在ssh serverlogincredentials上打开文件登录; login.setvalue(&#34;用户名&#34;&#34;用户名&#34;); login.setvalue(&#34;密码&#34;&# 34; password&#34;); login.setvalue(&#34; publickey&#34;&#34; /pel/to/key.pub&#34;); //默认值:&#34; $ home / .ssh / id_rsa.pub&#34; login.setvalue(&#34; privatekey&#34; / pitionalkey&#34; / pather&#34;); //默认值:&#34; $ home / .ssh / id_rsa&#34; login.setvalue(&#34; port#34;&#34; 999&#34;); //默认值:22fileHandle file2 = fs ::打开(&#34; ssh://example.com/home/user/readme.txt&#34;,&amp;登录);

此刻,无法在GlobalLevel注册新的文件系统。要使用自定义文件系统,请创建它的实例并使用AbstractFileSystem接口访问它。

文件句柄可用于访问其指向的文件系统对象的信息。还可以复制文件句柄,创建指向同一文件SystemObject的第二个句柄,但不继承以前句柄的状态。此操作仅将句柄的路径复制到那种廉价的操作。

//从本地文件systemfile handle文件= fs ::打开(&#34;数据/ readme.txt&#34;); //将第二个句柄到同一个FileFileHandle File2 = File;

一旦获得文件句柄,它可以用于查询文件系统对象的基本信息。

filehandle file = fs ::打开(&#34;数据/ readme.txt&#34;); //检查类型if(file.isfile())std :: cout&lt;&lt; &#34;文件&#34; &lt;&lt; std :: endl;否则if(file.isdirectory())std :: cout&lt;&lt; &#34;目录&#34; &lt;&lt; std :: endl;否则if(file.issymboliclink())std :: cout <&lt;&lt; &#34; Symlink&#34; &lt;&lt; std :: endl;否则if(!file.exists())std :: cout

仅在需要时检索文件信息,即,在上述功能之一的第一次调用上,然后在内存中缓存。当句柄的操作修改文件信息时,它会自动更新。然而,如果在应用程序之外修改文件或使用outcleHandle到同一文件的文件,则文件句柄无法知道更改。因此,必须手动更新:

使用FileHandle,可以执行基本文件操作。对于二进制操作,例如复制或移动,第二文件处理器被认为是操作的目标。根据特工,目标不需要已经存在。如果针对目录而不是文件的目标点,则目标将被认为是在该目录中(例如,文件将被复制给定目录的文件)。

filehandle dir = fs ::打开(&#34;数据&#34;); filehandle file = fs ::打开(&#34; readme.txt&#34;); filehandle dest; //如果(!dir.isdirectory())dir.createdirectory()尚未存在,如果尚不存在//将文件复制到Directoryfile.copy(dir); //将文件复制到另一个filedest = dir.open(&#34; readme2.txt&#34;); file.copy(dest); //重命名filefile.rename(&#34; Readme3.txt&#34;); //将文件移动到Directoryfile.move(dir)中; //创建硬链接nest = dir.open(&#34; readme4.txt&#34;); file.createlink(dest); //创建符号linkdest = dir.open(&#34; readme5.txt&#34;); file.createSymboliclink(dest); //删除filefile.remove(); //删除目录(仅当为空)dir.removedirectory();

要读取和写入文件,应用标准C ++流。要打开Afile的输入流,请调用CreateInputStream。要创建输出流,请调用createOutputStream。

高级文件操作包括生成文件的哈希和Base64编码。它们可以直接调用文件句柄:

filehandle file = fs ::打开(&#34; Readme.txt&#34;); //获取filestd的sha1哈希:: string hash = file.sha1(); //获取FISESTD :: String BASE64 = FILE.BASE64()的BASE64编码; //从base64编码文件编写文件.wilefilebase64(base64);

FileHandle用于访问文件以及目录。要检查文件句柄指向目录是否,可以使用函数ISDirectory。

filehandle dir = fs ::打开(&#34;数据&#34;); for(fileiterator它= dir.begin();它!= dir.end(); ++它){std :: string path = *它;}

为了自动遍历目录树,可以调用遍历遍历功能。它可以通过它

filehandle dir = fs ::打开(&#34;数据&#34;); //遍历所有文件entriesdir.traverse([](filehandle&amp; fh) - &gt; bool {std :: cout&lt;&lt; fh。path()&lt; std :: endl;返回true; //继续}); //遍历所有文件和目录Dir.traverse([](fileHandle&amp; fh) - &gt; bool {std :: cout&lt;&lt; fh。path()&lt; std :: endl;返回true; //继续},[](filehandle&amp; dir) - &gt; bool {std :: cout&lt; dir。path()&lt; st; std :: endl;返回true; //继续});

当获得对目录的句柄时,它可以用于打开相对于该目录的文件句柄:

filehandle dir = fs ::打开(&#34;数据&#34;); //打开parent directoryfilehandle parentdir = dir.parentdirectory(); //在DirectoryFileHandle File1中打开文件1 = Dir.open(&#34; Readme.txt&#34;); //相对于directoryfilehandle file2 = dir.open(&#34; readme.txt&#34;);

对于目录树上的更高级别操作,可以使用类树,差异和更改。树包含树数据结构中的所有文件和目录的信息。通过呼叫ReadTree可以从adirectory手柄获得。

//读取来自当前目录Std :: unique_ptr&lt; tree&gt的目录树; tree1 = dir.readtree(); //从当前目录中读取目录树,给它一个虚拟rootstd :: unique_ptr&lt; tree&gt; tree2 = dir.readtree(&#34; / root&#34;);

给定两个目录树,可以计算它们之间的差异,从而导致差异对象。差异包含许多文件系统操作,以便从源树TOTE DESTIVER树转换。这可以用来实现基本文件同步:

//打开DirectiesFileHandle SRCDIR = FS ::打开(&#34; data1&#34;); filehandle dstdir = fs ::打开(&#34; data2&#34;); //读取目录树自动srctree = srcdir.readtree();自动dsttree = dstdir.readtree(); //计算差异自动差异= dsttree-&gt; Creatediff(* srctree); // sync目录(更改更改:diff-&gt;更改()){if(更改。操作()==更改:: copyfile){filehandle src = srcdir。打开(改变。Path()); filehandle dst = dstdir。打开(改变。Path()); SRC。复制(DST); }如果(更改。操作()==更改:: copyDir){fileHandle SRC = SRCDIR。打开(改变。Path()); filehandle dst = dstdir。打开(改变。Path()); SRC。 CopyDirectoryRec(DST); }如果(更改。操作()== change :: removefile){filehandle dst = dstdir。打开(改变。Path()); DST。消除(); }如果(更改。操作()==更改:: recumentir){filehandle dst = dstdir。打开(改变。Path()); DST。 reameedirectoryrec(); }}