【Unity开发】FileStream 详解及用法指南

🐾 个人主页 🐾

阿松爱睡觉,横竖醒不来 🏅你可以不屠龙,但不能不磨剑🗡


文章目录

一、前言

先来了解一下什么是 FileStream

FileStreamSystem.IO 命名空间下的一个类,它继承自 Stream 抽象类,提供了对文件系统的字节级读写访问,并支持同步和异步操作,还可以控制文件访问方式(读、写、读写)和共享权限。主要有下面几个核心特性:

  1. 字节级操作:处理原始字节数据
  2. 随机访问:支持文件指针定位(Seek)
  3. 缓冲机制:内置缓冲区提高性能
  4. 线程安全:支持多线程访问(需适当同步)

对于简单的文本文件操作,可以考虑使用更高级的 StreamReader/StreamWriterFile 静态方法。但对于二进制文件处理、自定义文件格式或需要精细控制的情况,FileStream 是最佳选择。看下对比:

特性 FileStream StreamReader/Writer File类静态方法
访问级别 字节级 字符级 高级操作
控制粒度 精细 中等 粗粒度
适用场景 二进制文件、自定义格式 文本文件 简单文件操作
性能 取决于操作

二、FileStream 构造函数

简单的了解什么是FileStream 就可以了,想要快速的掌握上手,直接来看示例进行学习,以练促学。

先说下构造函数。FileStream 提供了多种构造函数,最常用的有:

csharp 复制代码
// 通过文件路径创建
public FileStream(string path, FileMode mode)

// 完整参数版本
public FileStream(string path, FileMode mode, FileAccess access, FileShare share)

// 使用文件句柄创建
public FileStream(SafeFileHandle handle, FileAccess access)

参数说明:

  • path:文件路径
  • mode :文件打开方式(FileMode 枚举)
  • access :访问权限(FileAccess 枚举)
  • share :共享权限(FileShare 枚举)

💡枚举的选择也是非常的重要,所以也要了解枚举的各种枚举值:

FileMode 枚举

描述 文件存在时 文件不存在时
CreateNew 创建新文件 抛出异常 创建新文件
Create 创建或覆盖 覆盖原文件 创建新文件
Open 打开现有文件 打开文件 抛出异常
OpenOrCreate 打开或创建 打开文件 创建新文件
Truncate 打开并清空 清空文件 抛出异常
Append 追加数据 打开并定位到末尾 创建新文件

FileAccess

  • Read:只读
  • Write:只写
  • ReadWrite:读写

FileShare

  • None:独占访问
  • Read:允许其他读取
  • Write:允许其他写入
  • ReadWrite:允许其他读写

三、基本读写操作

直接看两个最常用的实践示例:写文件读文件

(一)写入文件示例

csharp 复制代码
using (FileStream fs = new FileStream("test.txt", FileMode.Create))
{
    string text = "Hello, FileStream!";
    byte[] bytes = Encoding.UTF8.GetBytes(text);
    fs.Write(bytes, 0, bytes.Length);
    fs.Flush(); // 确保数据写入磁盘
}

(二)读取文件示例

csharp 复制代码
using (FileStream fs = new FileStream("test.txt", FileMode.Open))
{
    byte[] buffer = new byte[fs.Length];
    int bytesRead = fs.Read(buffer, 0, buffer.Length);
    string text = Encoding.UTF8.GetString(buffer, 0, bytesRead);
    Console.WriteLine(text);
}

在进行读写文件的操作的时候有两个最常见问题,那就是文件正在被另一个程序占用,以及操作的文件太大。看下具体的问题示例已经对应的解决方案:

文件被占用异常

csharp 复制代码
try
{
    using (FileStream fs = new FileStream("file.txt", FileMode.Open))
    {
        // 操作文件
    }
}
catch (IOException ex)
{
    Console.WriteLine($"文件访问错误: {ex.Message}");
}

大文件处理

csharp 复制代码
const int bufferSize = 1024 * 1024; // 1MB
byte[] buffer = new byte[bufferSize];

using (FileStream fs = new FileStream("large.iso", FileMode.Open))
{
    int bytesRead;
    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
    {
        // 处理数据块
    }
}

在操作文件的时候还要注意性能优化,下面列举了几个优化性能的核心点:

  1. 使用缓冲区:适当增大缓冲区大小

    csharp 复制代码
    int bufferSize = 4096; // 4KB
    using (var fs = new FileStream("large.bin", FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize))
  2. 批量读写:减少小数据块的频繁操作

  3. 使用异步API:对于大文件或高并发场景

  4. 及时释放资源 :始终使用 using 语句或手动调用 Dispose()


四、开发案例

学会了基本的读写操作之外,就是如何使用读写操作去实现一些较为复杂功能了,下面就是几个比较常见的案例:

(一)文件复制工具

csharp 复制代码
void CopyFile(string source, string destination)
{
    const int bufferSize = 4096;
    byte[] buffer = new byte[bufferSize];
    
    using (FileStream src = new FileStream(source, FileMode.Open))
    using (FileStream dest = new FileStream(destination, FileMode.Create))
    {
        int bytesRead;
        while ((bytesRead = src.Read(buffer, 0, buffer.Length)) > 0)
        {
            dest.Write(buffer, 0, bytesRead);
        }
    }
}

(二)文件加密/解密

csharp 复制代码
void EncryptFile(string inputPath, string outputPath, byte[] key)
{
    using (FileStream inFile = new FileStream(inputPath, FileMode.Open))
    using (FileStream outFile = new FileStream(outputPath, FileMode.Create))
    {
        byte[] buffer = new byte[1024];
        int bytesRead;
        
        for (int i = 0; i < key.Length; i++)
        {
            inFile.ReadByte(); // 跳过头部
        }
        
        while ((bytesRead = inFile.Read(buffer, 0, buffer.Length)) > 0)
        {
            for (int i = 0; i < bytesRead; i++)
            {
                buffer[i] ^= key[i % key.Length]; // 简单XOR加密
            }
            outFile.Write(buffer, 0, bytesRead);
        }
    }
}

五、高级功能

(一)随机访问(Seek)

csharp 复制代码
using (FileStream fs = new FileStream("data.bin", FileMode.Open))
{
    // 定位到第100个字节
    fs.Seek(100, SeekOrigin.Begin);
    
    // 读取10个字节
    byte[] buffer = new byte[10];
    fs.Read(buffer, 0, 10);
}

(二)异步操作

csharp 复制代码
async Task WriteFileAsync()
{
    using (FileStream fs = new FileStream("async.txt", FileMode.Create))
    {
        byte[] bytes = Encoding.UTF8.GetBytes("Async data");
        await fs.WriteAsync(bytes, 0, bytes.Length);
    }
}

(三)文件锁定机制

csharp 复制代码
// 独占方式打开文件,阻止其他进程访问
using (var fs = new FileStream("locked.txt", 
       FileMode.OpenOrCreate, 
       FileAccess.ReadWrite, 
       FileShare.None))
{
    // 处理文件...
}
相关推荐
想做后端的前端1 小时前
Unity-UIGI优化Rebatch与Rebuild
unity
淡海水3 小时前
12-02-性能-数据结构性能调查案例1-5
数据结构·性能优化·c#
Java的搬运工3 小时前
使用 C# 轻松管理 PDF 文件的用户权限
c#·用户权限
玖玥拾13 小时前
Unity Shader 基础与图形学(一)
unity·图形渲染·图形学·shader
Neil201316 小时前
ajax跨域请求
c#
唐青枫17 小时前
别把 Razor 当成几段 HTML:C#.NET Razor Pages、MVC 视图与实战详解
c#·.net
百里香酚兰1 天前
【Unity学习笔记】如何把粉色Prefab还原
笔记·学习·unity
专注仿真1 天前
CMO模型文档-活动单元基类
c#·模型·cmo·活动单元基类
xcLeigh1 天前
Unity基础:使用Transform控制物体旋转——Rotate与LookAt详解
unity·教程·transform·rotate·lookat