【.NET Core】深入理解IO - FileSteam流

简介: 【.NET Core】深入理解IO - FileSteam流

一、IO流概述

抽象类Stream支持读取和写入字节。所有表示流的类都继承自Stream类。Stream类及其派生类提供数据源和存储库的常见视图。

流主要设计三个基本的操作:

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

IO流常用的流包含一下几个类,博主将在将来的博文中一一介绍。


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

二、文件流FileStream

2.1 FileStream概述

使用FileStream类读取、写入、打开和关闭文件系统上的文件,以及操作其他与文件相关的操作句柄、包括管道、标注输入和标注输出。可以使用Write和方法执行同步操作,或者ReadAsyncCopyToAsyncWriteAsync以及FlushAsync执行异步操作的方法。FlushReadCopyTo使用异步方法执行资源密集型文件操作,而不阻止主线程。


FileStream类实现IDisposable接口。在使用完类型后,你应直接或间接释放类型。如要直接释放类型,请在try/catch块中调用其Dispose方法。如要间接释放类型,请使用using语言构造。

2.2 FileStream检测流位置更改

FileStream当对象在其句柄上没有独占保留时,另一个线程可以同时访问文件句柄,并更改与文件句柄关联的操作系统文件指针的位置。在这种情况下,对象中的FileStream缓存位置以及缓冲区中缓存的数据可能会受到损害。该FileStream对象定期对访问缓存缓冲区的方法执行检查,以确保操作系统的句柄位置与对象使用的FileStream缓存位置相同。


2.3 FileStream构造函数

  • FileStream(String,FileMode)

使用指定的路径和创建模式初始化FileStream类的新实例。

  • FileStream(String,FileStreamOptions)

使用指定的路径、创建模式、读/写和共享权限、缓存区大小、其他文件选项、预分配大小及其FileStream对同一文件的访问权限初始化类的新实例FileSteam

  • FileStream(String,FileMode,FileAccess)

使用指定的路径、创建模式和读/写权限初始化FileStream类新实例。

  • FileStream(String,FileMode,FileAccess,FileShare,Int32,Boolean)

使用指定的路径、创建模式、读/写和共享权限、缓冲区大小和同步或异步状态初始化FileStream类的新实例。

  • FileStream(String,FileMode,FileAccess,FileShare)

使用指定的路径、创建模式、读/写权限和共享权限创建 FileStream类的新实例

  • FileStream(String,FileModel,FileAccesss,FileShare,Int32,FileOptions)

使用指定的路径、创建模式、读/写和共享权限、其他 FileStreams 可以具有的对此文件的访问权限、缓冲区大小和附加文件选项初始化FileStream类的新实例。

2.4 FileStream常用属性

1717428460780.png

2.5 FileStream.Read方法

从流中读取字节块并将该数据写入给定缓冲区中

  • 重载


序号 方法 说明
1 Read(Byte[],Int32,Int32) 从流中读取字节块并将该数据写入给定缓冲区中
2 Read(Span) 从当前文件流中读取字节序列,并在该文件流中按照读取的字节数提升位置。
  • 注解

方法Read 中offset参数(开始读取的缓冲区索引)提供字节array的偏移量,参数count提供要从此流中读取的最大字节数。返回的值是读取的实际字节数。如果到达流的末尾,则返回的值为零。如果读取操作成功,则流的当前位置将按读取的字节数前进。如果发生异常,流的当前位置保持不变。


方法Read仅在到达流的末尾后返回零,否则,Read始终在返回之前至少从流中读取一个字节。如果在调用Read时流中没有数据可用,则方法将阻塞,直到至少可以返回一个字节的数据。实现可以自由返回比请求的字节少,即使尚未到达流的末尾。

  • 示例
public void FileReadDemo()
{
    string pathSource = @"c:\tests\source.txt";
    try
    {
       using (FileStream fsSource = new FileStream(pathSource,
                                                   FileMode.Open,
                                                   FileAccess.Read))
        {
            byte[] bytes = new byte[fsSource.Length];
            int numBytesToRead = (int)fsSource.Length;
            int numBytesRead = 0;
            while (numBytesToRead > 0)
            {
                int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
                if (n == 0)
                    break;
                numBytesRead += n;
                numBytesToRead -= n;
            }
             numBytesToRead = bytes.Length;
            using (FileStream fsNew = new FileStream(pathNew,
                FileMode.Create, FileAccess.Write))
            {
                fsNew.Write(bytes, 0, numBytesToRead);
            }
        }
    }
    catch(FileNotFoundException fileStreamException)
    {
        Console.WriteLine(fileStreamException.Message)    
    }
}

2.6 FileStream.Write方法

将字节的序列从只读范围写入当前文件流,并按写入的字节数向前移动此文件流中的当前位置。

  • 重载
序号 方法 说明
1 Write(ReadOnlySpan) 将字节的序列从只读范围写入当前文件流,并按写入的字节数向前移动此文件流中的当前位置
2 Write(Byte[],Int32,Int32) 将字节块写入文件流。
  • 注解

CanWrite使用,属性确定当前实例是否支持写入。WriteAsync使用方法以异步方式写入当前流。

如果吸入操作成功,则文件流中的位置将按写入的字节数前进。如果发生异常,则文件流中的位置保持不变。

  • 示例
if(fileStream.Length == 0)
{
    tempString =lastRecordText + recordNumber.ToString();
    fileStream.Write(uniEncoding.GetBytes(tempString),0,uniEncoding.GetByteCount(tempString));
}

2.7 FileStream.Seek方法

将该流的当前位置设置为给定值。

public override long Seek (long offset, System.IO.SeekOrigin origin);
  • offset 相对于origin的点,从此处开始查找。
  • SeekOrigin 使用SeekOrigin 类型的值,将开始位置,结束位置或当前位置指定为offset的参考点。
  • 示例
public static void Main()
{
   long offset;
   int nextByte;
   using (FileStream fs = new FileStream(@"c:\temp\alphabet.txt", FileMode.Open, FileAccess.Read))
   {
        for (offset = 1; offset <= fs.Length; offset++)
        {
            fs.Seek(-offset, SeekOrigin.End);
            Console.Write((char)fs.ReadByte());
        }
        Console.WriteLine();
        fs.Seek(20, SeekOrigin.Begin);
        while ((nextByte = fs.ReadByte()) > 0)
        {
            Console.Write((char)nextByte);
         }
         Console.WriteLine();
    }
}

2.8 FileStream.Flush 方法

调用FileStream.Flush方法时,会刷新操作系统I/O缓冲区。


I/O缓冲区只有调用Flush或释放对象才会释放缓冲区,否则不会刷新流的编码器。如将StreamWriter.AutoFlush为true表示数据将从缓冲区刷新到流,但不会刷新编码器状态。这允许编码器将其状态保留,以便可以正确编码一下字符块。


三、FileStream总结

上面介绍了FileStream的一般用法,如果需要有异常操作,异步读取使用ReadAsync方法,使用ReadAsync方法 可以执行资源密集型文件操作,而不会阻止main线程。 异步写入使用WriteAsync方法,WriteAsync方法可以执行资源密集型文件操作,而不会阻止main线程。在选择FileStream时,根据实际的使用场景选择对应的方法完成对流的操作。

目录
相关文章
|
5天前
|
开发框架 前端开发 .NET
asp.net core 使用 AccessControlHelper 控制访问权限
asp.net core 使用 AccessControlHelper 控制访问权限
|
17天前
|
Cloud Native API C#
C#的现代化:.NET Core引领的技术革命
【6月更文挑战第9天】`.NET Core引领C#现代化,实现跨平台革命,提升性能并支持云原生应用。异步编程模型优化体验,统一API简化开发流程。C#应用场景扩展,开发效率提高,技术创新加速,预示其未来在技术领域将持续发挥关键作用。`
29 10
|
22天前
|
安全 C#
【.NET Core】深入理解IO - 读取器和编写器
【.NET Core】深入理解IO - 读取器和编写器
29 5
|
21天前
|
前端开发 Java C#
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
|
21天前
|
XML 开发框架 人工智能
C#/.NET/.NET Core拾遗补漏合集(24年5月更新)
C#/.NET/.NET Core拾遗补漏合集(24年5月更新)
|
21天前
|
开发框架 .NET API
ASP.NET Core Web中使用AutoMapper进行对象映射
ASP.NET Core Web中使用AutoMapper进行对象映射
|
20天前
|
开发框架 .NET Linux
【.NET Developer】已发布好的.NET Core项目文件如何打包为Docker镜像文件
该文介绍了如何不使用VS2019手动创建ASP.NET Core Blazor项目的Dockerfile并构建Docker镜像。首先,创建名为Dockerfile的文件,并复制提供的Dockerfile内容,该文件指定了基础镜像和工作目录。然后,通过CMD在项目目录下运行`docker build -t 自定义镜像名 .`来生成镜像。最后,使用`docker run`命令启动容器并验证项目运行。此外,文章还提到了将镜像推送到Azure Container Registry (ACR)的步骤。
|
20天前
|
Linux C# C++
【.NET Developer】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
本文介绍了如何使用VS2019和.NET框架创建一个Blazor应用,并将其部署到Azure应用服务。首先,Blazor是一个使用C#而非JavaScript构建交互式Web UI的框架,支持共享服务器和客户端应用逻辑,以及与Docker和Azure集成。任务包括创建Blazor项目,配置Dockerfile为Linux容器,本地测试,发布到Azure Container Registry (ACR),然后在Azure App Service for Container上部署。在部署过程中,需确保Docker设置正确,开启ACR的Admin访问权限,并监控镜像拉取和容器启动日志。
|
22天前
|
存储 开发框架 缓存
【.NET Core】你真的了解HttpRuntime类吗
【.NET Core】你真的了解HttpRuntime类吗
12 0
|
22天前
|
前端开发 C#
【.NET Core】你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟
【.NET Core】你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟
55 0