第三章 文件系统操作

第三章 文件系统操作


 文件路径 (FilePath)


    在tango库中,文件和目录存储单位通常用FilePath实例来描述。
创建一个FilePath很简单,用char[]提供构造器。文件路径不包含ANSI字符,而采用UTF-8编码。如下例:

 


auto path = new FilePath(“name”);


    创建一文件和文件夹需要区分开,创建文件用path.create,创建文件夹用

 

path.createFolder


    重命名一个文件会把它从一个地方移动到另一个地方:


path.rename(”/directory/otherfilename”);


    复制一个文件保留它的原始时间戳:


path.copy("source.name");


    删除一个文件或文件夹用path.remove
    列举文件夹内容用


foreach(name;path.toList)
//do something with the contained file or folder name


有一个另外的低级toList()通过委托进行更强大地控制:


path.toList(void delegate(char[] parent, char[] name,bool isDir) dg );


这个toList()版本会用于构建自定义文件访问器,并且用于#FileScan模块

 

 


FilePath异常

 


    底层操作系统检测到一个错误就抛出一个IO异常。如试图移除一个不存在的或只读的文件将产生一个异常。

 

 

文件管道 (FileConduit)

 

    (注意,文件管道在0.99.8版中已重命名到tango.io.device.File模块,相应的,使用FileConduit的地方改为File)


    文件访问设计意图是通过文件管道(FileConduit)进行操作,提供包括流访问和随机访问文件内容的方法。


    打开一个文件读取内容用如下形式:


auto conduit = new FileConduit(“myFilePath”);


    打开一个文件用于读和写操作需要明确声明文件类型:


auto conduit = new FileConduit(“myFilePath”,FileConduit.WriteCreate);


    有一些预定义类型变体,包括附加(appending)、只读(read-only)、读写(read-write)等等。另外的类型可以被定义,使用一些系统级标记的组合。


    文件管道(FileConduit)使我们可以直接访问未知类型的文件内容。在本例下面这个例子中,我们直接复制一个文件到控制台:


//打开一个文件用于读
auto from = new FileConduit(“test.txt”);
//显示文件内容到控制台
Stdout.stream.copy(from);
现在我们复制一个文件到另一个里边:
//打开一个文件用于读
auto from = new FileConduit(“test.txt”);
//打开另一个文件用于写
auto to = new FileConduit(“copy.txt”,FileConduit.WriteCreate);
//复制文件
to.output.copy(from);
加载一个实体文件到内存,可考虑使用如下形式:
//打开一个文件用于读
auto file = new FileConduit(“test.txt”);
//创建一个数组容纳实体文件
auto content = new char[file.length];
//读取文件内容,返回值是读取的字节数
auto bytesRead = file.input.read(content)
相反,也可以直接写内容到一个文件管道,如下:
//打开个文件用于写
auto to = new FileConduit(“test.txt”,FileConduit.WriteCreate);
//写一个数组内容到该文件
auto bytesWritten = to.output.write(content);


文件管道(FileConduit)同样支持随机IO,在本例中,我们使用seek()重定向文件位置,增加了一点风味,利用一个草案(reader&writer对)进行简单的输入输出类型测定:
//打开一个文件用于读和写
auto file = new FileConduit(“random.bin”,FileConduit.ReadWriteCreate);
//绑定一个草案(protocol)到该管道
auto read = new Reader(file);
auto write = new Writer(file);
int x = 10;
char[] y = “hello”;
//write data,and flush output since protocol IO is buffered
Write(x)(y)();
//重定向到文件开始
File.seek(0);
//重新读回数据
Read(x)(y);

 

 

 

    注意上面的例子中,我们使用了缓冲IO(buffered IO),通过草案(protocol),因而需要在重新确定当前文件位置前冲洗输出。


    当我们不需要更长时间使用时,每个文件管道(FileConduit)应该明确地关闭。为此目的,可以方便地使用一个scope表达式。


auto file = new FileConduit(“myFilePath”);
scope(exit)
File.close;


    大体积文件没有完全地完成或复制操作不完整时,IO异常将被抛出。例如,当使用一个不可用的文件时。

 


文件 (File)

 


    File是一个简单的类,用于读写或再次添加文件内容,例如读取全部文件内容:


auto file = new File(“myfile”);
auto content = file.read();


    基本的文件在调用返回前被关闭。File应该避免假定文件内容,因此,上面的例子返回一个无类型数组。当和文本文件一起工作,它要强制转换返回值去阐述正确的数据类型。文本文件通常转换成一个字符数组(char[]):


auto file = new File(“myfile”);
auto content = cast(char[])file.read();


    转换一个文本文件到一系列行,试试下面的形式:


import Text=tango.text.Util;
auto file = new File(“myfile”);
auto content = cast(char[])file.read();
auto lines = Text.splitLines(content);
使用一个foreach来迭代:
Foreach(line;Text.lines(content))
//针对每一行做某事


    文件可以设置成一个数组的内容:


char[] myText;
file.write(myText);


 文件内容添加用类似的方式:


char[] myText;
file.append(myText);


    以上这些每个方法属于FilePath,通过path方法被展示。因此你能获取文件大小,重新确定文件位置,移除它等等。

 


File异常

 


    底层操作系统或文件系统错误发生时,File 抛出一个IO异常,如尝试写一个只读文件。

 


文件系统 (FileSystem)

 


    这里展示各种文件系统控制,现在文件系统(FileSystem)提供取回和设置当前工作目录和转换一个路径成它的绝对路径形式的便利。访问当前目录名如下操作:


auto name = FileSystem.getDirectory;


    改变当前目录是类似的。
absolutePath方法接受一个FilePath实例,然后转换它到相应的当前工作目录的绝对路径形式,绝对路径形式通常开始于一个路径分隔符,或一个存储标识符,并且不包括’.’或’..’在路径的任何地方。如果提供的路径已经是绝对的,就返回一个未经改变的。

 


FileSystem 异常

 


     取回或设置当前目录失败将抛出一个异常。传递一个无效路径给absolutePath(绝对路径)将产生一个异常。

 


文件根(FileRoots)

 


    文件系统的存储设备显示在这里,在win32平台,根(roots)描述为设备字母,在linux平台,通过/etc/mtab/描述设备定位。列举文件存储设备是可行的:


foreach(name;FilrRoots.list)
//针对每个name做某事


FileRoots 异常


    下层的操作系统或文件系统错误发生时,将抛出一个IO异常。


文件扫描(浏览)(FileScan)


    FileScan模块封装FilePath.toList,以提供更多具体方法。主要的特征是FileScan再次提起文件夹树(folder-trees),并且生成一个容纳文件和文件夹的列表。产生一个D文件和它们所在文件夹的列表的例程如下:


import tango.io.FileScan;
auto scan = new FileScan;
scan(new FilePath(“.”,”.d”);
foreach(folder;scan.folders)
Cout(folder).newline;
foreach(file;scan.files)
Cout(file).newline;


    这个例子执行一次扫描,穿过所有结尾为“.d”的文件,在当前目录开始,一直扩展到所有子目录,每个文件夹包含的文件被显示到控制台,随后形成一个文件名清单。


FileScan有许多方法重载上面那个过分简单化的文件过滤例子,使用委托(delegate):


bool delegate(FilePath path,bool isDir)


    委托的返回值为true就添加实例,否则就排除它。参数isDir指出实例是否是一个文件夹或文件。

 


FileScan异常

 


没有明确的异常抛出

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值