【C#进阶五】C#中常用I/O流介绍、 FileStream类及FileMode、FileAccess、FileShare

在这里插入图片描述


流可以视为一组连续的一维数据,包含开头和结尾,并且其中的游标指示了流的当前位置。抽象基类 Stream支持读取和写入字节。

涉及三个基本操作:

  • 读取 :将数据从流传输到数据结构(如字节数组)中。
  • 写入 : 将数据从数据源传输到流。
  • 查找 :对流中的当前位置进行查询和修改。

1 常见的流

C#中由许多类型的流(14种派生类),但是在处理文件输入/输出时,最重要的类型为FileStream类,它提供了读取或写入文件的方式。

C#中常见的流:

  • FileStream: 用于对文件进行读取和写入操作。
  • IsolatedStorageFileStream:用于对独立存储中的文件进行读取或写入操作。
  • MemoryStream:用于作为后备存储对内存进行读取和写入操作,读取速度比FileStream快。
  • BufferedStream :用于改进读取和写入操作的性能。
  • NetworkStream: 用于通过网络套接字进行读取和写入。
  • PipeStream: 用于通过匿名和命名管道进行读取和写入。
  • CryptoStream :用于将数据流链接到加密转换

2 先总结一下FileMode、FileAccess、FileShare

1.FileMode 指定操作系统打开文件的方式

FileMode 参数控制文件是覆盖、创建、打开还是某种组合。 用于 Open 打开现有文件。 若要追加到文件,请使用 Append。 若要截断文件或创建文件(如果不存在),请使用 Create

Append若存在文件,则打开该文件并查找到文件尾,或者创建一个新文件。 FileMode.Append 只能与 FileAccess.Write 一起使用。
Create指定操作系统应创建新文件。 如果此文件已存在,则会将其覆盖。
CreateNew指定操作系统应创建新文件, 这需要 Write权限。
Open指定操作系统应打开现有文件。
OpenOrCreate指定操作系统应打开文件(如果文件存在);否则,应创建新文件。
Truncate指定操作系统应打开现有文件。 该文件被打开时,将被截断为零字节大小。

2.FileAccess 定义文件的读取、写入或读/写访问权限的常量

Read对文件的读访问。 可从文件中读取数据。 与 Write 组合以进行读写访问。
ReadWrite对文件的读写访问权限。 可从文件读取数据和将数据写入文件。
Write文件的写访问。 可将数据写入文件。 与 Read 组合以进行读写访问。

3.FileShare包含用于控制其他 FileStream 对象对同一文件可以具有的访问类型的常数。

Delete允许随后删除文件。
Inheritable使文件句柄可由子进程继承。 Win32 不直接支持此功能。
None谢绝共享当前文件。 文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。
Read允许随后打开文件读取。 如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。 但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
ReadWrite允许随后打开文件读取或写入。 如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。 但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。
Write允许随后打开文件写入。 如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。 但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。

3 FileStream类

为文件提供 Stream,既支持同步读写操作,也支持异步读写操作。

3.1 常用构造方法、属性和方法

构造方法、属性和方法描述
FileStream(String, FileMode, FileAccess, FileShare, Int32, FileOptions)构造方法,使用指定的路径、创建模式、读/写和共享权限、其他 FileStreams 可以具有的对此文件的访问权限、缓冲区大小和附加文件选项初始化 FileStream类的新实例。
CanRead如果流支持读取,则为 true;如果流已关闭或是通过只写访问方式打开的,则为 false
CanSeek该值指示当前流是否支持查找
CanTimeout该值确定当前流是否可以超时
IsAsyncFileStream 是异步打开还是同步打开的。
Length获取流的长度(以字节为单位)
Name获取 FileStream 中已打开的文件的绝对路径。
Position获取或设置此流的当前位置。
BeginRead(Byte[], Int32, Int32, AsyncCallback, Object)开始异步读操作。Byte[]:读取存入数组中,第一个Int32:数组开始读取的位置,第二个int32:数组最大的长度。AsyncCallback:异步处理后回调的方法(回调可理解为:B的方法在被A触发的情况下去调用了A的方法。)
Close()关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)。
CopyTo(Stream, Int32)使用指定的缓冲区大小,从当前流中读取字节并将其写入到另一流中。Stream:复制到的流,Int32:缓冲区的大小。
Dispose()释放由 Stream使用的所有资源。
Lock(Int64, Int64)防止其他进程读取或写入。第一个Int64要锁定的范围的起始处、第二个Int64要锁定的范围。
Read(Byte[], Int32, Int32)从流中读取字节块并将该数据写入给定缓冲区中。其中:第一个int32中的字节偏移量,将在此处放置读取的字节,第二个int32最多读取的字节数。
Read(Span< Span >)从当前文件流中读取字节序列,并在该文件流中按照读取的字节数提升位置。
ReadByte()从文件中读取一个字节,并将读取位置提升一个字节。
Seek(Int64, SeekOrigin)将该流的当前位置设置为给定值。Int64:参数的字节偏移量offset。SeekOrigin :类型的值,将开始位置、结束位置或当前位置指定为 offset 的参考点。有三个值:Begin(从流的起始位置开始跳跃) Current(继续在当前的Position位置上进行跳跃) End(直接跳到结尾处)。如果 offset 为负,则需要在由指定的字节数之前指定的新位置 origin offset 。 如果 offset 为零 (0) ,则新位置需要是指定的位置 origin 。 如果 offset 为正,则需要在由指定的字节数后跟随新位置 origin offset 。例如:aFile.Seek(-5,SeekOrigin.End); 从文件的末尾向前查找五个字节。
ToString()返回表示当前对象的字符串。
WriteByte(Byte)一个字节写入文件流中的当前位置。
Write(Byte[], Int32, Int32)将字节块写入文件流
Flush(Boolean)清除此流的缓冲区,将所有缓冲数据都写入到文件中,并且也清除所有中间文件缓冲区。

3.2 代码示例

  public static void Main()
    {
        string path = @"G:\Desktop\archive1\MyTest.txt";
        // 如果文件存在则删除文件
        if (File.Exists(path))
        {
            File.Delete(path);
        }
        //创建文件
        using (FileStream fs = File.Create(path))
        {
            AddText(fs, "This is some text");
            AddText(fs, "This is some more text,");
            AddText(fs, "\r\nand this is on a new line");
            AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
            for (int i = 1; i < 124; i++)
            {
                AddText(fs, Convert.ToChar(i).ToString());
            }
        }
        //打开流并读取
        using (FileStream fs = File.OpenRead(path))
        {
            //每一次读取字节的长度
            byte[] b = new byte[2];
            //将该流的当前位置设置为给定值,从流尾向前读五个字节
            fs.Seek(-5, SeekOrigin.End);
            //给定字节编码格式
            UTF8Encoding temp = new UTF8Encoding(true);
            while (fs.Read(b, 0, b.Length) > 0)
            {
                Console.Write(temp.GetString(b)+" ");
                Console.WriteLine();
            }
            Console.WriteLine(fs.Name);
        }
        using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
        { // 
            UTF8Encoding temp = new UTF8Encoding(true);
            for (int i = 0; i < fs.Length; i++)
            {
                byte[] bytes = new byte[1];
                bytes[0] = (byte)fs.ReadByte();
                Console.Write(temp.GetString(bytes) +" ");               
            }
            if (fs.CanRead)
            {
                Console.WriteLine("可读");
            }
            else
            {
                Console.WriteLine("不可读");
            }
        }
    }
    private static void AddText(FileStream fs, string value)
    {
        //给定编码格式的字节数组
        byte[] info = new UTF8Encoding(true).GetBytes(value);
        //写入字节数组
        fs.Write(info, 0, info.Length);
    }

运行结果:

image-20220825154718936

wx
yz
{z
G:\Desktop\archive1\MyTest.txt
  h i s   i s   s o m e   t e x t T h i s   i s   s o m e   m o r e   t e x t ,
 a n d   t h i s   i s   o n   a   n e w   l i n e

 T h e   f o l l o w i n g   i s   a   s u b s e t   o f   c h a r a c t e r s :
      
               1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { 可读

欢迎关注公众号【智能建造小硕】(分享计算机编程、人工智能、智能建造、日常学习和科研经验等,欢迎大家关注交流。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

智能建造小硕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值