UPL2-14——File Access 模块

关于文件读写相关,可见:

  1. U2L10——Resources资源动态加载
  2. UH1——AssetBundle
  3. U4S4——可寻址资源管理系统 Addressables
  4. UN4L6——WWW类 和 UN4L8——UnityWebRequest类
  5. UD4L2——文件相关、UD4L3——文件流相关、UD4L4——文件夹相关

File Access 模块

File Access(文件访问)模块,主要用于监控 游戏运行过程中 对文件系统的访问情况的,显示 游戏在运行时 读取或写入文件的行为

主要包括

  1. 读取资源(如 Textures、音频、文本)的行为
  2. 写入日志、存档文件 的行为
  3. 加载 Addressables​ 或 AssetBundle 的行为
  4. 使用 File.ReadAllText​、WWW​、UnityWebRequest 等 API 的行为
  5. StreamingAssets​、PersistentDataPath​、Resources 等目录交互 的行为

等等

我们一般出现以下情况时可以排查此处

  1. 游戏卡顿、掉帧问题

    比如进入某个场景或者界面时突然卡顿,可以看看是不是有大量资源文件被同步加载或读写磁盘操作

  2. I/O高峰排查(特别是低端设备)

    某些平台(尤其是老旧安卓设备)磁盘读取速度慢,频繁读取大文件会造成性能抖动,可以定位是否 I/O 是瓶颈

  3. 资源未预加载问题排查

    某些资源在运行时频繁加载,可判断是否应该预加载进内存或放进 AssetBundle

  4. 存档、日志写入频率分析

    频繁写入磁盘会对 存储 设备造成压力,有时可能是后台日志写入或读取导致存储性能下降

  5. 加载性能分析

    检查是否存在同步(阻塞主线程)的文件访问,确认 AssetBundle​ 或 Addressable 加载过程中的磁盘瓶颈

等等

File Access中各参数功能的含义和作用

image

  • 文件访问(File Access)监视视图

    image

    • Files Opened(文件开启): 游戏在当前帧或某时间段内打开的文件数量,比如加载纹理、音频、场景文件等会触发打开文件操作

      频繁打开文件可能意味着资源未预加载、重复打开,可能会导致性能问题

    • Files Closed(文件关闭): 游戏中被关闭的文件数量,通常在加载完成后资源被释放或使用完毕后关闭

      若 opened 和 closed 长期不平衡,可能会造成文件句柄泄漏

    • File Seeks(文件寻找): 文件读取时,跳转文件指针位置的次数,即不是顺序读,而是随机跳到某个偏移再读(如 .seek() 操作)

      Seek 过多说明文件访问不连续,可能降低 IO 性能(特别是硬盘上)

    • Reads in Flight: 正在进行中的文件读取操作数量。比如异步读取纹理、音频、AssetBundle 过程中

      这个值过高说明系统在并发读很多文件,可能会造成带宽瓶颈

    • File Handles Open: 当前仍然保持打开状态的文件句柄数量,每个打开的文件占用一个操作系统资源

      如果这个值长期偏高,说明打开的文件没有及时关闭,可能导致:

      1. 系统资源耗尽
      2. 加载失败
      3. 在移动端甚至会直接 崩溃(因 文件描述符 数量限制)

    使用建议:开发阶段常开启 Profiler 的 File Access 面板,在加载资源、切换场景时重点观察:

    1. 是否有文件重复打开(Files Opened)
    2. 是否及时关闭(Files Closed)
    3. 是否出现大量 Random Seek(File Seeks)
    4. 是否有文件读取卡顿(Reads in Flight 持续偏高)
  • 文件汇总视图

    image

    • Filename:访问的文件名
    • Total Bytes Read:从该文件中读取的总字节数
    • Read Access Time (ms):该文件所有读取操作的累计耗时
    • Access Count:访问该文件的总次数
    • First frame:该文件第一次被访问的帧编号
    • Number of Frames:该文件跨越了多少帧被访问

    关注点:

    1. 是否有频繁重复读取?(Access Count 很高)
    2. 是否跨帧访问?(Number of Frames > 1)
    3. 是否读取量大?(Total Bytes Read 很高)
    4. 是否读取慢?(Read Access Time 偏高)
  • 访问汇总视图

    image

    • Index:文件访问操作的编号(用于排序或识别多个访问记录)。
    • FileName:被访问的文件名。
    • Type:访问类型,例如 Read、Write、Seek 等。
    • Access Size:本次访问读取或写入的数据大小(单位:字节)
    • Offset:本次访问在文件中的偏移量(即从文件哪个位置开始读写)
    • Duration(ms):本次访问所用的时间(单位:毫秒),用于判断读写耗时。
    • Avg Bandwidth(MBps):平均传输速率(单位:MB/s),用于评估 I/O 性能。
    • First Frame Index:本次访问首次出现在第几帧。
    • Frames:本次访问持续了多少帧。
    • Thread:执行此访问的线程名称,比如 Main Thread 或某个 Worker 线程。

    主要关注内容:

    1. 检查是否有 大文件频繁访问 或 高延迟文件读写
    2. 排查哪些文件在运行时被意外地读入磁盘(如加载未打入 AssetBundle 的资源)
    3. 判断是否存在磁盘 IO 性能瓶颈
    4. 对应线程查看是否是主线程同步 I/O 操作导致卡顿
    5. 分析 Seek 和多次小块读取导致性能下降的情况

File Access 对于我们的意义

它可以帮助我们

  1. 进行性能优化

    排查出不该在运行时做的磁盘操作,改为异步加载或预加载

  2. 排查资源管理问题

    分析是否资源管理不当,如频繁读取 Resources​ 或 StreamingAssets

  3. 排查优化平台兼容性

    排查优化低端设备上 I/O 速度慢造成的卡顿问题

  4. 路径问题排查

    检查是否有无效或异常的读写路径(如路径拼错、重复加载)

  5. 同步加载的性能问题分析

    如果你看到 File Access 中的操作出现在主线程(Main Thread),且耗时超过几 ms,说明该读写可能是性能瓶颈
    应考虑进行优化,比如:使用异步加载 API、对大资源进行预加载、合理规划资源加载时机

等等