.NET中的IO体系介绍

.net中对于IO流的支持分为两个层次:基于字节和基于字符两种方式。

 

基于字节的方式:
基于字节的方式适用于任何场合,因为任何文件的数据都是基于字节的方式有序存放的。基于字节的方式适用于操作二进制文件,比如exe文件、视频、音频文件等等。
Stream抽象类是所有基于字节方式的流的父类。Stream及其子类具有三个方面的特征:
支持从流读取。可以从流中读取单个字节或者一次性读取多个字节,将读取到的多个字节存储到字节数组中。
支持向流写入。可以向流中写入单个字节或者一次性写入多个字节,如果要一次性写入多个字节,可以将多个字节构成一个字节数组,作为写入方法的参数。
支持查找。不过这个特性在其某些子类中就不支持,比如网络流。
 
Stream类及其部分子类UML图
Stream的常用方法定义:
public abstract void Write(byte[] buffer, int offset, int count);
上面的方法作用是将buffer这个字节数组中从offset字节开始的count个字节写入到流中,并且将流的位置向前推进写入的字节个数个字节。
public abstract void WriteByte(byte value);
上面的方法是一次向流中写入一个字节,并且将流的位置向前推进一个字节。
public abstract void Read(byte[] buffer, int offset, int count);
上面的方法作用是从流中第offset字节开始的count个字节读入到buffer这个字节数组中,并且将流的位置向前推进读取的字节个数个字节。
public abstract int ReadByte(); 上面的方法是从流中读取一个字节,并且将流的位置向前推进一个字节,如果已经达到流的结尾,则返回-1
继承Stream抽象类的子类有: System.Data.OracleClient.OracleBFile:表示托管 OracleBFile 对象,该对象的设计旨在与 Oracle BFILE 数据类型配合使用。  System.Data.OracleClient.OracleLob:表示存储在 Oracle 服务器上的大型对象二进制 (LOB) 数据类型。 System.IO.BufferedStream:给另一流上的读写操作添加一个缓冲层。 System.IO.Compression.DeflateStream:提供用于使用 Deflate 算法压缩和解压缩流的方法和属性。 System.IO.Compression.GZipStream:提供用于压缩和解压缩流的方法和属性。 System.IO.FileStream:公开以文件为主的 Stream,既支持同步读写操作,也支持异步读写操作。 System.IO.MemoryStream:创建其支持存储区为内存的流。 System.Net.Sockets.NetworkStream:提供用于网络访问的基础数据流。 System.Security.Cryptography.CryptoStream:定义将数据流链接到加密转换的流。
基于字符的方式
对于东亚语系的国家而言,每个字符都是占用两个字节(采用Unicode编码),每次向文件读取和写入的时候基于字节的方式相对较为繁琐:写入的时候需要将字符串转换成字节数组,读取的时候需要将读取到的字节数组转换成字符串。为此,.net提供了一种更直接的方式,那就是基于字符的操作。
基于字符的方式相对就方面多了,我们可以指定一次性读/写入多个字符,或者一次性读/写入一行,或者一次性写入一个字符串,或者一次性将流中的所有字符读取。
在.net中基于字符的方式对流进行读写分别是由两个抽象类及其子类来完成的。
基于字符的方式读取
 
TextReader的常见方法定义:
public virtual int Peek();
这个方法的作用是:读取下一个字符,而不更改读取器状态或字符源。返回下一个可用字符,而实际上并不从输入流中读取此字符。
public virtual int Read();
这个方法的作用是:读取输入流中的下一个字符并使该字符的位置提升一个字符。这个方法的返回值,如果到流的末尾,则返回-1。
public virtual int Read (char[] buffer, int index, int count);
这个方法的作用是:从当前流中读取最大 count 的字符并从 index 开始将该数据写入 buffer。这个方法的返回值小于或等于 count,具体取决于流中是否有可用的数据。如果调用此方法时没有更多的字符留下可供读取,则此方法返回 0。
public virtual void ReadBlock(char[] buffer, int index, int count);
这个方法的作用是:从当前流中读取最大 count 的字符并从 index 开始将该数据写入 buffer。这个方法的返回值表示当前实际读取的字符数,如果已经达到文件的末尾,则返回值将小于count。
public virtual string ReadLine();
这个方面的作用是:从当前流中读取一行字符并将数据作为字符串返回。
public virtual string ReadToEnd();
这个方法的作用是:读取从当前位置到 TextReader 的结尾的所有字符并将它们作为一个字符串返回。
基于字符的方式写入
 
TextWriter抽象类常见方法及解释:
public virtua lvoid Flush();
这个方法的作用是:清理当前编写器的所有缓冲区,使所有缓冲数据写入基础设备。
public virtual void Write(char value);
这个方法的作用是:将字符写入文本流。
public virtual void Write(char[] buffer);
这个方法的作用是:将字符数组写入文本流。
public virtual void Write(char[] buffer,int index,int count);
这个方法的作用是:将字符的子数组写入文本流。
public virtual void Write(string format, object[] arg0);
这个方法的作用是:使用与 String.Format 相同的语义写出格式化的字符串。
用法示例:
using System;

using System.Collections.Generic;

using System.Text;

using System.IO;



namespace IODemo

{

/// <summary>

/// 说明:基于字节的方式读写流的例子。

/// 作者:周公

/// 日期:2008-6-30

/// 原文地址:http://blog.csdn.net/zhoufoxcn

/// </summary>

public class StreamDemo

{

private string fileName;

/// <summary>

/// 要进行读写的文件全路径

/// </summary>

public string FileName

{

get { return fileName; }

set { fileName = value; }

}

/// <summary>

/// 基于字节的方式写文件流

/// </summary>

/// <param name="message"></param>

public void WriteFile(string message)

{

if (fileName != null)

{

FileInfo file = new FileInfo(fileName);

FileStream stream = null;

//将要写入的字符串转换成utf8编码的字节数组

byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);

if (!file.Exists)

{

//如果不存在指定文件则创建指定文件

stream = file.Create();

}

else

{

//否则打开打开文件流

stream = file.OpenWrite();

}

//将字符串转换的字节数组写入到流中

stream.Write(buffer, 0, buffer.Length);

stream.Close();//关闭流

}

else

{

throw new ArgumentNullException("没有指定文件名异常");

}

}

/// <summary>

/// 基于字节的方式读文件流

/// </summary>

/// <returns></returns>

public string ReadMessage()

{

string result = string.Empty;

if (fileName != null)

{

FileInfo file = new FileInfo(fileName);

FileStream stream = file.OpenRead();

byte[] buffer = new byte[(int)file.Length];

stream.Read(buffer, 0, (int)(file.Length));

//将读取到的字符串按照utf8方式转换成字符串

result = System.Text.Encoding.UTF8.GetString(buffer);

stream.Close();//关闭流

}

else

{

throw new ArgumentNullException("没有指定文件名异常");

}

return result;

}



}

}
基于字符的方式:
using System;

using System.Collections.Generic;

using System.Text;

using System.IO;



namespace IODemo

{

/// <summary>

/// 说明:基于字符的方式读写流的例子。

/// 作者:周公

/// 日期:2008-6-30

/// 原文地址:http://blog.csdn.net/zhoufoxcn

/// </summary>

public class TextDemo

{

private string fileName;

/// <summary>

/// 要进行读写的文件全路径

/// </summary>

public string FileName

{

get { return fileName; }

set { fileName = value; }

}

/// <summary>

/// 基于字符的方式写文件流

/// </summary>

/// <param name="message"></param>

public void WriteFile(string message)

{

if (fileName != null)

{

FileInfo file = new FileInfo(fileName);

FileStream stream = null;

StreamWriter writer = null;

if (!file.Exists)

{

//如果不存在指定文件则创建指定文件

stream = file.Create();

}

else

{

//否则打开打开文件流

stream = file.OpenWrite();

}

writer = new StreamWriter(stream);

//将字符串写入流中

writer.Write(message);

writer.Close();

stream.Close();//关闭流



}

else

{

throw new ArgumentNullException("没有指定文件名异常");

}

}

/// <summary>

/// 基于字符的方式读文件流

/// </summary>

/// <returns></returns>

public string ReadMessage()

{

string result = string.Empty;

if (fileName != null)

{

FileInfo file = new FileInfo(fileName);

FileStream stream = file.OpenRead();

StreamReader reader = new StreamReader(stream);

//一次性读入所有字符

result = reader.ReadToEnd();

reader.Close();

stream.Close();//关闭流



}

else

{

throw new ArgumentNullException("没有指定文件名异常");

}

return result;

}

}

}

 

posted @ 2010-04-03 19:39  逆时针  阅读(1299)  评论(1编辑  收藏  举报