.NET 4.0在文件IO等方面添加了一些类和方法,提高了IO操作的效率和使用的方便性。
1. 文件读写方面的增强
如读取一个很大的csv文件,然后对读取的每行数据进行处理。
在.NET 2.0时代,我们读取时,可以使用File.ReadAllLines方法读取所有的行,返回string类型的数组,然后遍历处理数组的每个string。
var
lines
=
File.ReadAllLines(
@"
c:/a.csv
"
);
foreach
(
var
s
in
lines)
{
//
...
}
这个方法的缺点很明显,如果文件较大,会占用太多内存,并且是所有内容载入内存后才能开始接下来的处理,效率不高。
如果进行改进,可以用TextReader类来处理,于是有了下面的代码:
using
(TextReader reader
=
new
StreamReader(
@"
c:/a.csv
"
))
{
string
line
=
null
;
while
((line
=
reader.ReadLine())
!=
null
)
{
//
...
}
}
但这个方法不如File.ReadAllLines简单直观。
.NET 4.0增加了File.ReadLines方法,保留了高效并且直观的优点,该方法的原型如下:
public static IEnumerable<string> ReadLines(string path);
返回IEnumerable<string>接口类型,可以用foreach遍历。
var
lines
=
File.ReadLines(
@"
c:/a.csv
"
);
foreach
(
var
line
in
lines)
{
//
...
}
这个方法并不是一次将数据加载到内存,而是按需索取,这就杜绝了高内存占用和延迟等待。
相似的,如果将内容追加或写入到文件,可以用WriteAllLines(string path, IEnumerable<string> contents)方法。该方法原形为:
public
static
void
WriteAllLines(
string
path, IEnumerable
<
string
>
contents);
IEnumerable
<
string
>
content
=
//
...;
File.WriteAllLines(
@"
c:/a.csv
"
, content);
2. 文件目录遍历方面的增强
如果想遍历一个目录下的文件或目录,常用下面的代码:
var
files
=
Directory.GetFiles(
@"
c:/windows
"
);
foreach
(
var
file
in
files)
{
//
...
}
var
dirs
=
Directory.GetDirectories(
@"
c:/windows
"
);
foreach
(
var
dir
in
dirs)
{
//
...
}
这样遍历存在同样的问题:取得所有的子项后程序才能继续执行,内存占用等。
.NET 4.0中添加了Directory.EnumerateDirectories,Directory.EnumerateFiles等方法及其重载来提高目录文件遍历的效率:
public
static
IEnumerable
<
string
>
EnumerateDirectories(
string
path);
public
static
IEnumerable
<
string
>
EnumerateFiles(
string
path);
3. 内存映射文件。
.NET 4.0增加了对内存映射文件的支持。
内存映射文件的概念在Windows早就存在,以前的.NET版本可以通过调用API实现内存映射文件。
内存映射文件是一个文件到一块内存区域的映射,这块内存区域位于进程的虚拟地址空间与某个文件的部分或全部内容建立映射。可以与已有的文件建立映射,也可以直接创建内存映射文件。
系统用内存映射文件加载和执行exe/dll文件。节省了Page file的空间,加快程序的执行速度。
内存映射文件也是有效的进程间通信机制,实际上所有的进程间通信机制都是基于内存映射文件的[windows 核心编程]
操作内存映射文件的类位于System.IO.MemoryMappedFiles中。
实例:进程间通信
创建内存映射文件,并往文件写入内容。
using
(
var
file
=
MemoryMappedFile.CreateNew(
"
MemoryMappedFile
"
,
1024
))
{
using
(BinaryWriter bw
=
new
BinaryWriter(file.CreateViewStream()))
{
bw.Write(
"
Blog: http://www.xianfen.net
"
);
Process pr
=
Process.Start(
"
test.exe
"
);
Console.ReadKey();
}
}
打开内存映射文件,并读取内容。
using
(MemoryMappedFile file
=
MemoryMappedFile.OpenExisting(
"
MemoryMappedFile
"
))
{
using
(BinaryReader br
=
new
BinaryReader(file.CreateViewStream()))
{
Console.WriteLine(br.ReadString());
}
}