.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;

        }

    }

}
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux的IO体系结构可以分为七层。首先是虚拟文件系统层(VFS层),它负责处理内核与各种文件系统的交互。不同的文件系统可能有不同的数据结构和方法,因此需要通过VFS层来统一接口[1]。 接下来是文件系统层,它包括各种具体的文件系统实现,如EXT4、NTFS等。文件系统层负责管理文件和目录的存储和访问。 在上面的层次之下是块设备层,它处理块设备(如硬盘)的读写操作。块设备层提供了缓存、调度、以及与设备驱动程序的交互。 接下来是设备驱动程序层,它负责与硬件设备进行通信。设备驱动程序将硬件抽象为逻辑设备,并提供相应的接口供上层调用。在非PC体系结构上,由于无法直接引用物理内存单元的线性地址来访问I/O共享存储器,Linux定义了一些依赖于体系结构的函数,如直接内存访问(DMA)。 再下一层是总线层,它负责管理硬件设备的连接和通信。总线层提供了一组标准接口,用于与设备进行通信。 设备层位于总线层之上,它将逻辑设备映射到实际硬件设备,并提供了一组通用的设备操作接口。 最底层是物理设备层,它包括了具体的硬件设备,如硬盘、网卡等。 总结起来,Linux的IO体系结构包括虚拟文件系统层、文件系统层、块设备层、设备驱动程序层、总线层、设备层和物理设备层。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [如何提高Linux下块设备IO的整体性能?](https://download.csdn.net/download/weixin_38705762/15468690)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [深入理解 Linux 内核---I/O 体系结构和设备驱动程序](https://blog.csdn.net/u012319493/article/details/85097182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周公

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值