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

🐾 个人主页 🐾

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


文章目录

一、前言

先来了解一下什么是 FileStream?

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

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

对于简单的文本文件操作,可以考虑使用更高级的 StreamReader/StreamWriter 或 File 静态方法。但对于二进制文件处理、自定义文件格式或需要精细控制的情况,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))
{
    // 处理文件...
}
相关推荐
Leinwin34 分钟前
Copilot Studio 实战:多模型选择、GitHub Copilot harness 计费与 Copilot Credits 额度管理
开发语言·c#
FuckPatience1 小时前
C# Winform 使用Label循环显示闪烁
开发语言·c#
念何架构之路1 小时前
OpenTelemetry核心概念
后端·目标跟踪·golang·c#·linq
开开心心就好1 小时前
电脑语音实时转文字工具,会议记录很省事
运维·服务器·前端·c#·ocr·perl·1024程序员节
波力海苔夹心脆6752 小时前
C# 固高 GTS 运动控制卡入门:伺服上下电、Jog 点动与二维插补(WinForms 实战)
服务器·开发语言·c#·运动控制·伺服电机·winforms·固高
何以解忧唯有撸码8 小时前
c# + YOLODotNet+OpenCVSharp 实现物品轨迹追踪
计算机视觉·c#·winform·yolov8·opencvsharp
凯基迪科技16 小时前
Unity游戏加密锁逆向方案、选型与攻防分析
游戏·unity·游戏引擎
阿松爱学习18 小时前
【Unity开发】局部区域截图功能实现
unity·c#
zhanghaha131419 小时前
C# 系列教程_1 基础语法篇(面向新手系统教程)
开发语言·c#
昂好的day20 小时前
固高运动控制卡实战(下):点位运动与直线/圆弧插补 API 详解
开发语言·c#